diff options
author | 3gg <3gg@shellblade.net> | 2024-03-09 08:43:26 -0800 |
---|---|---|
committer | 3gg <3gg@shellblade.net> | 2024-03-09 08:43:26 -0800 |
commit | adbd2511beec8f1caa1752bdfd755cc2f62ba425 (patch) | |
tree | 8fde167e9d9951b43e571a2417ae55f9572bea28 | |
parent | 4bc4ca2796bd434880b77d3c4bcbb56107456777 (diff) |
Make isogfx a library instead of an executable.
-rw-r--r-- | game/src/game.c | 27 | ||||
-rw-r--r-- | gfx-app/include/gfx/gfx_app.h | 53 | ||||
-rw-r--r-- | gfx-app/src/gfx_app.c | 6 | ||||
-rw-r--r-- | gfx-iso/CMakeLists.txt | 29 | ||||
-rw-r--r-- | gfx-iso/app/app.h | 12 | ||||
-rw-r--r-- | gfx-iso/app/checkerboard.h | 9 | ||||
-rw-r--r-- | gfx-iso/app/isogfx-demo.h | 9 | ||||
-rw-r--r-- | gfx-iso/demos/CMakeLists.txt | 2 | ||||
-rw-r--r-- | gfx-iso/demos/checkerboard/CMakeLists.txt | 15 | ||||
-rw-r--r-- | gfx-iso/demos/checkerboard/checkerboard.c (renamed from gfx-iso/app/checkerboard.c) | 92 | ||||
-rw-r--r-- | gfx-iso/demos/isomap/CMakeLists.txt | 15 | ||||
-rw-r--r-- | gfx-iso/demos/isomap/isomap.c (renamed from gfx-iso/app/isogfx-demo.c) | 91 | ||||
-rw-r--r-- | gfx-iso/include/isogfx/app.h | 22 | ||||
-rw-r--r-- | gfx-iso/src/app.c (renamed from gfx-iso/app/main.c) | 111 | ||||
-rw-r--r-- | gfx-iso/tools/mkasset.py (renamed from gfx-iso/asset/mkasset.py) | 0 |
15 files changed, 259 insertions, 234 deletions
diff --git a/game/src/game.c b/game/src/game.c index c720656..dc4ab84 100644 --- a/game/src/game.c +++ b/game/src/game.c | |||
@@ -39,6 +39,10 @@ static const int WIDTH = 1350; | |||
39 | static const int HEIGHT = 900; | 39 | static const int HEIGHT = 900; |
40 | static const int MAX_FPS = 60; | 40 | static const int MAX_FPS = 60; |
41 | 41 | ||
42 | typedef struct GfxAppState { | ||
43 | Game game; | ||
44 | } GfxAppState; | ||
45 | |||
42 | /// Initialize the game's plugin. | 46 | /// Initialize the game's plugin. |
43 | static bool init_plugin(Game* game) { | 47 | static bool init_plugin(Game* game) { |
44 | assert(game); | 48 | assert(game); |
@@ -113,17 +117,11 @@ static void resize_plugin(Game* game, int width, int height) { | |||
113 | 117 | ||
114 | void app_end(Game* game); | 118 | void app_end(Game* game); |
115 | 119 | ||
116 | bool app_init(const GfxAppDesc* desc, void** app_state) { | 120 | bool app_init(Game* game, int argc, const char** argv) { |
117 | assert(desc); | 121 | assert(game); |
118 | |||
119 | if (desc->argc <= 1) { | ||
120 | LOGE("Usage: %s <plugin> [plugin args]", desc->argv[0]); | ||
121 | return false; | ||
122 | } | ||
123 | 122 | ||
124 | Game* game = calloc(1, sizeof(Game)); | 123 | if (argc <= 1) { |
125 | if (!game) { | 124 | LOGE("Usage: %s <plugin> [plugin args]", argv[0]); |
126 | LOGE("Failed to allocate game state"); | ||
127 | return false; | 125 | return false; |
128 | } | 126 | } |
129 | 127 | ||
@@ -131,8 +129,8 @@ bool app_init(const GfxAppDesc* desc, void** app_state) { | |||
131 | // | 129 | // |
132 | // Here we consume the <plugin> arg so that plugins receive the remainder | 130 | // Here we consume the <plugin> arg so that plugins receive the remainder |
133 | // args starting from 0. | 131 | // args starting from 0. |
134 | game->argc = desc->argc - 1; | 132 | game->argc = argc - 1; |
135 | game->argv = desc->argv + 1; | 133 | game->argv = argv + 1; |
136 | 134 | ||
137 | char exe_path_buf[NAME_MAX] = {0}; | 135 | char exe_path_buf[NAME_MAX] = {0}; |
138 | if (readlink("/proc/self/exe", exe_path_buf, sizeof(exe_path_buf)) == -1) { | 136 | if (readlink("/proc/self/exe", exe_path_buf, sizeof(exe_path_buf)) == -1) { |
@@ -152,7 +150,7 @@ bool app_init(const GfxAppDesc* desc, void** app_state) { | |||
152 | goto cleanup; | 150 | goto cleanup; |
153 | } | 151 | } |
154 | 152 | ||
155 | const char* plugin = desc->argv[1]; | 153 | const char* plugin = argv[1]; |
156 | if (!(game->plugin = load_plugin(game->plugin_engine, plugin))) { | 154 | if (!(game->plugin = load_plugin(game->plugin_engine, plugin))) { |
157 | goto cleanup; | 155 | goto cleanup; |
158 | } | 156 | } |
@@ -168,7 +166,6 @@ bool app_init(const GfxAppDesc* desc, void** app_state) { | |||
168 | goto cleanup; | 166 | goto cleanup; |
169 | } | 167 | } |
170 | 168 | ||
171 | *app_state = game; | ||
172 | return true; | 169 | return true; |
173 | 170 | ||
174 | cleanup: | 171 | cleanup: |
@@ -223,4 +220,4 @@ void app_resize(Game* game, int width, int height) { | |||
223 | resize_plugin(game, width, height); | 220 | resize_plugin(game, width, height); |
224 | } | 221 | } |
225 | 222 | ||
226 | GFX_APP_MAIN(WIDTH, HEIGHT, MAX_FPS); | 223 | GFX_APP_MAIN(WIDTH, HEIGHT, MAX_FPS, "Game"); |
diff --git a/gfx-app/include/gfx/gfx_app.h b/gfx-app/include/gfx/gfx_app.h index 86c502a..ffff4bc 100644 --- a/gfx-app/include/gfx/gfx_app.h +++ b/gfx-app/include/gfx/gfx_app.h | |||
@@ -2,6 +2,8 @@ | |||
2 | 2 | ||
3 | #include <stdbool.h> | 3 | #include <stdbool.h> |
4 | 4 | ||
5 | typedef struct GfxAppState GfxAppState; | ||
6 | |||
5 | /// Application settings. | 7 | /// Application settings. |
6 | typedef struct GfxAppDesc { | 8 | typedef struct GfxAppDesc { |
7 | int argc; // Number of application arguments. | 9 | int argc; // Number of application arguments. |
@@ -11,21 +13,22 @@ typedef struct GfxAppDesc { | |||
11 | int max_fps; // Desired maximum display framerate. 0 to disable. | 13 | int max_fps; // Desired maximum display framerate. 0 to disable. |
12 | double update_delta_time; // Desired delta time between frame updates. | 14 | double update_delta_time; // Desired delta time between frame updates. |
13 | const char* title; // Window title. | 15 | const char* title; // Window title. |
16 | GfxAppState* app_state; | ||
14 | } GfxAppDesc; | 17 | } GfxAppDesc; |
15 | 18 | ||
16 | typedef bool (*GfxAppInit)(const GfxAppDesc*, void** app_state); | 19 | typedef bool (*GfxAppInit)(GfxAppState*, int argc, const char** argv); |
17 | typedef void (*GfxAppUpdate)(void* app_state, double t, double dt); | 20 | typedef void (*GfxAppShutdown)(GfxAppState*); |
18 | typedef void (*GfxAppRender)(void* app_state); | 21 | typedef void (*GfxAppUpdate)(GfxAppState*, double t, double dt); |
19 | typedef void (*GfxAppResize)(void* app_state, int width, int height); | 22 | typedef void (*GfxAppRender)(GfxAppState*); |
20 | typedef void (*GfxAppShutdown)(void* app_state); | 23 | typedef void (*GfxAppResize)(GfxAppState*, int width, int height); |
21 | 24 | ||
22 | /// Application callback functions. | 25 | /// Application callback functions. |
23 | typedef struct GfxAppCallbacks { | 26 | typedef struct GfxAppCallbacks { |
24 | GfxAppInit init; | 27 | GfxAppInit init; |
28 | GfxAppShutdown shutdown; | ||
25 | GfxAppUpdate update; | 29 | GfxAppUpdate update; |
26 | GfxAppRender render; | 30 | GfxAppRender render; |
27 | GfxAppResize resize; | 31 | GfxAppResize resize; |
28 | GfxAppShutdown shutdown; | ||
29 | } GfxAppCallbacks; | 32 | } GfxAppCallbacks; |
30 | 33 | ||
31 | typedef enum Key { | 34 | typedef enum Key { |
@@ -68,21 +71,25 @@ bool gfx_is_key_pressed(Key); | |||
68 | 71 | ||
69 | /// Define a main function that initializes and puts the application in a loop. | 72 | /// Define a main function that initializes and puts the application in a loop. |
70 | /// See also: gfx_app_run(). | 73 | /// See also: gfx_app_run(). |
71 | #define GFX_APP_MAIN(WIDTH, HEIGHT, MAX_FPS) \ | 74 | #define GFX_APP_MAIN(WIDTH, HEIGHT, MAX_FPS, TITLE) \ |
72 | int main(int argc, const char** argv) { \ | 75 | int main(int argc, const char** argv) { \ |
73 | gfx_app_run( \ | 76 | GfxAppState app_state = {0}; \ |
74 | &(GfxAppDesc){ \ | 77 | gfx_app_run( \ |
75 | .argc = argc, \ | 78 | &(GfxAppDesc){ \ |
76 | .argv = argv, \ | 79 | .argc = argc, \ |
77 | .width = WIDTH, \ | 80 | .argv = argv, \ |
78 | .height = HEIGHT, \ | 81 | .width = WIDTH, \ |
79 | .max_fps = MAX_FPS, \ | 82 | .height = HEIGHT, \ |
80 | .update_delta_time = MAX_FPS > 0 ? 1.0 / (double)MAX_FPS : 0.0}, \ | 83 | .max_fps = MAX_FPS, \ |
81 | &(GfxAppCallbacks){ \ | 84 | .update_delta_time = MAX_FPS > 0 ? 1.0 / (double)MAX_FPS : 0.0, \ |
82 | .init = (GfxAppInit)app_init, \ | 85 | .title = TITLE, \ |
83 | .update = (GfxAppUpdate)app_update, \ | 86 | .app_state = &app_state, \ |
84 | .render = (GfxAppRender)app_render, \ | 87 | }, \ |
85 | .resize = (GfxAppResize)app_resize, \ | 88 | &(GfxAppCallbacks){ \ |
86 | .shutdown = (GfxAppShutdown)app_end}); \ | 89 | .init = (GfxAppInit)app_init, \ |
87 | return 0; \ | 90 | .update = (GfxAppUpdate)app_update, \ |
91 | .render = (GfxAppRender)app_render, \ | ||
92 | .resize = (GfxAppResize)app_resize, \ | ||
93 | .shutdown = (GfxAppShutdown)app_end}); \ | ||
94 | return 0; \ | ||
88 | } | 95 | } |
diff --git a/gfx-app/src/gfx_app.c b/gfx-app/src/gfx_app.c index e0211b1..a93756c 100644 --- a/gfx-app/src/gfx_app.c +++ b/gfx-app/src/gfx_app.c | |||
@@ -9,7 +9,7 @@ | |||
9 | 9 | ||
10 | /// Application state. | 10 | /// Application state. |
11 | typedef struct GfxApp { | 11 | typedef struct GfxApp { |
12 | void* app_state; | 12 | GfxAppState* app_state; |
13 | GfxAppCallbacks callbacks; | 13 | GfxAppCallbacks callbacks; |
14 | int max_fps; | 14 | int max_fps; |
15 | double update_delta_time; | 15 | double update_delta_time; |
@@ -79,6 +79,7 @@ bool gfx_app_run(const GfxAppDesc* desc, const GfxAppCallbacks* callbacks) { | |||
79 | 79 | ||
80 | bool success = false; | 80 | bool success = false; |
81 | 81 | ||
82 | g_gfx_app.app_state = desc->app_state; | ||
82 | g_gfx_app.callbacks = *callbacks; | 83 | g_gfx_app.callbacks = *callbacks; |
83 | g_gfx_app.max_fps = desc->max_fps; | 84 | g_gfx_app.max_fps = desc->max_fps; |
84 | g_gfx_app.update_delta_time = desc->update_delta_time; | 85 | g_gfx_app.update_delta_time = desc->update_delta_time; |
@@ -110,7 +111,8 @@ bool gfx_app_run(const GfxAppDesc* desc, const GfxAppCallbacks* callbacks) { | |||
110 | glfwMakeContextCurrent(g_gfx_app.window); | 111 | glfwMakeContextCurrent(g_gfx_app.window); |
111 | 112 | ||
112 | // Initialize the application's state before setting any callbacks. | 113 | // Initialize the application's state before setting any callbacks. |
113 | if (!(*g_gfx_app.callbacks.init)(desc, &g_gfx_app.app_state)) { | 114 | if (!(*g_gfx_app.callbacks.init)( |
115 | g_gfx_app.app_state, desc->argc, desc->argv)) { | ||
114 | LOGE("Failed to initialize application"); | 116 | LOGE("Failed to initialize application"); |
115 | goto cleanup; | 117 | goto cleanup; |
116 | } | 118 | } |
diff --git a/gfx-iso/CMakeLists.txt b/gfx-iso/CMakeLists.txt index 993bbb3..673cb68 100644 --- a/gfx-iso/CMakeLists.txt +++ b/gfx-iso/CMakeLists.txt | |||
@@ -2,33 +2,42 @@ cmake_minimum_required(VERSION 3.0) | |||
2 | 2 | ||
3 | project(isogfx) | 3 | project(isogfx) |
4 | 4 | ||
5 | set(CMAKE_C_STANDARD 11) | 5 | set(CMAKE_C_STANDARD 17) |
6 | set(CMAKE_C_STANDARD_REQUIRED On) | 6 | set(CMAKE_C_STANDARD_REQUIRED On) |
7 | set(CMAKE_C_EXTENSIONS Off) | 7 | set(CMAKE_C_EXTENSIONS Off) |
8 | 8 | ||
9 | # isogfx | ||
10 | |||
9 | add_library(isogfx | 11 | add_library(isogfx |
10 | src/isogfx.c) | 12 | src/isogfx.c) |
11 | 13 | ||
12 | target_include_directories(isogfx PUBLIC | 14 | target_include_directories(isogfx PUBLIC |
13 | include) | 15 | include) |
14 | 16 | ||
15 | target_link_libraries(isogfx PRIVATE | 17 | target_link_libraries(isogfx PUBLIC |
16 | filesystem | 18 | filesystem |
17 | mem | 19 | mem |
18 | mempool) | 20 | mempool) |
19 | 21 | ||
20 | target_compile_options(isogfx PRIVATE -Wall -Wextra -Wpedantic) | 22 | target_compile_options(isogfx PRIVATE -Wall -Wextra -Wpedantic) |
21 | 23 | ||
22 | # Demo | 24 | # App |
23 | 25 | ||
24 | project(isogfx-app) | 26 | add_library(isogfx-app |
27 | src/app.c) | ||
25 | 28 | ||
26 | add_executable(isogfx-app | 29 | target_include_directories(isogfx-app PUBLIC |
27 | app/checkerboard.c | 30 | include) |
28 | app/isogfx-demo.c | ||
29 | app/main.c) | ||
30 | 31 | ||
31 | target_link_libraries(isogfx-app PRIVATE | 32 | target_link_libraries(isogfx-app PUBLIC |
32 | gfx | ||
33 | gfx-app | 33 | gfx-app |
34 | isogfx) | 34 | isogfx) |
35 | |||
36 | target_link_libraries(isogfx-app PRIVATE | ||
37 | gfx) | ||
38 | |||
39 | target_compile_options(isogfx-app PRIVATE -Wall -Wextra -Wpedantic) | ||
40 | |||
41 | # Demos | ||
42 | |||
43 | add_subdirectory(demos) | ||
diff --git a/gfx-iso/app/app.h b/gfx-iso/app/app.h deleted file mode 100644 index 25e55eb..0000000 --- a/gfx-iso/app/app.h +++ /dev/null | |||
@@ -1,12 +0,0 @@ | |||
1 | #pragma once | ||
2 | |||
3 | typedef struct IsoGfx IsoGfx; | ||
4 | typedef struct IsoGfxApp IsoGfxApp; | ||
5 | |||
6 | typedef struct IsoGfxApp { | ||
7 | int pixel_scale; // 0 or 1 for 1:1 scale. | ||
8 | void* state; | ||
9 | void (*shutdown)(IsoGfx*, void* state); | ||
10 | void (*update)(IsoGfx*, void* state, double t, double dt); | ||
11 | void (*render)(IsoGfx*, void* state); | ||
12 | } IsoGfxApp; | ||
diff --git a/gfx-iso/app/checkerboard.h b/gfx-iso/app/checkerboard.h deleted file mode 100644 index 61725a5..0000000 --- a/gfx-iso/app/checkerboard.h +++ /dev/null | |||
@@ -1,9 +0,0 @@ | |||
1 | #pragma once | ||
2 | |||
3 | #include "app.h" | ||
4 | |||
5 | #include <stdbool.h> | ||
6 | |||
7 | typedef struct IsoGfxApp IsoGfxApp; | ||
8 | |||
9 | bool make_checkerboard_app(IsoGfx*, IsoGfxApp*); | ||
diff --git a/gfx-iso/app/isogfx-demo.h b/gfx-iso/app/isogfx-demo.h deleted file mode 100644 index d099824..0000000 --- a/gfx-iso/app/isogfx-demo.h +++ /dev/null | |||
@@ -1,9 +0,0 @@ | |||
1 | #pragma once | ||
2 | |||
3 | #include "app.h" | ||
4 | |||
5 | #include <stdbool.h> | ||
6 | |||
7 | typedef struct IsoGfxApp IsoGfxApp; | ||
8 | |||
9 | bool make_demo_app(IsoGfx*, IsoGfxApp*); | ||
diff --git a/gfx-iso/demos/CMakeLists.txt b/gfx-iso/demos/CMakeLists.txt new file mode 100644 index 0000000..c0a4101 --- /dev/null +++ b/gfx-iso/demos/CMakeLists.txt | |||
@@ -0,0 +1,2 @@ | |||
1 | add_subdirectory(checkerboard) | ||
2 | add_subdirectory(isomap) | ||
diff --git a/gfx-iso/demos/checkerboard/CMakeLists.txt b/gfx-iso/demos/checkerboard/CMakeLists.txt new file mode 100644 index 0000000..f178262 --- /dev/null +++ b/gfx-iso/demos/checkerboard/CMakeLists.txt | |||
@@ -0,0 +1,15 @@ | |||
1 | cmake_minimum_required(VERSION 3.0) | ||
2 | |||
3 | project(checkerboard) | ||
4 | |||
5 | set(CMAKE_C_STANDARD 17) | ||
6 | set(CMAKE_C_STANDARD_REQUIRED On) | ||
7 | set(CMAKE_C_EXTENSIONS Off) | ||
8 | |||
9 | add_executable(checkerboard | ||
10 | checkerboard.c) | ||
11 | |||
12 | target_link_libraries(checkerboard PRIVATE | ||
13 | isogfx-app) | ||
14 | |||
15 | target_compile_options(checkerboard PRIVATE -Wall -Wextra -Wpedantic) | ||
diff --git a/gfx-iso/app/checkerboard.c b/gfx-iso/demos/checkerboard/checkerboard.c index 8b394c4..9730aea 100644 --- a/gfx-iso/app/checkerboard.c +++ b/gfx-iso/demos/checkerboard/checkerboard.c | |||
@@ -1,12 +1,9 @@ | |||
1 | #include "isogfx-demo.h" | 1 | #include <isogfx/app.h> |
2 | |||
3 | #include <gfx/gfx_app.h> | ||
4 | #include <isogfx/isogfx.h> | 2 | #include <isogfx/isogfx.h> |
5 | 3 | ||
6 | #include <assert.h> | 4 | #include <assert.h> |
7 | #include <stdbool.h> | 5 | #include <stdbool.h> |
8 | #include <stdio.h> | 6 | #include <stdio.h> |
9 | #include <stdlib.h> | ||
10 | 7 | ||
11 | static const int TILE_WIDTH = 64; | 8 | static const int TILE_WIDTH = 64; |
12 | static const int TILE_HEIGHT = TILE_WIDTH / 2; | 9 | static const int TILE_HEIGHT = TILE_WIDTH / 2; |
@@ -34,11 +31,11 @@ typedef enum Colour { | |||
34 | Red, | 31 | Red, |
35 | } Colour; | 32 | } Colour; |
36 | 33 | ||
37 | typedef struct State { | 34 | typedef struct IsoGfxAppState { |
38 | Tile red; | 35 | Tile red; |
39 | int xpick; | 36 | int xpick; |
40 | int ypick; | 37 | int ypick; |
41 | } State; | 38 | } IsoGfxAppState; |
42 | 39 | ||
43 | static void make_checkerboard(IsoGfx* iso, Tile black, Tile white) { | 40 | static void make_checkerboard(IsoGfx* iso, Tile black, Tile white) { |
44 | assert(iso); | 41 | assert(iso); |
@@ -52,17 +49,36 @@ static void make_checkerboard(IsoGfx* iso, Tile black, Tile white) { | |||
52 | } | 49 | } |
53 | } | 50 | } |
54 | 51 | ||
55 | static void shutdown(IsoGfx* iso, void* app_state) { | 52 | static bool init( |
53 | IsoGfxAppState* state, IsoGfx* iso, int argc, const char** argv) { | ||
54 | assert(state); | ||
56 | assert(iso); | 55 | assert(iso); |
57 | if (app_state) { | 56 | |
58 | free(app_state); | 57 | if (!isogfx_make_world( |
58 | iso, &(WorldDesc){ | ||
59 | .tile_width = TILE_WIDTH, | ||
60 | .tile_height = TILE_HEIGHT, | ||
61 | .world_width = WORLD_WIDTH, | ||
62 | .world_height = WORLD_HEIGHT})) { | ||
63 | return false; | ||
59 | } | 64 | } |
65 | |||
66 | const Tile black = isogfx_make_tile(iso, &tile_set[Black]); | ||
67 | const Tile white = isogfx_make_tile(iso, &tile_set[White]); | ||
68 | state->red = isogfx_make_tile(iso, &tile_set[Red]); | ||
69 | make_checkerboard(iso, black, white); | ||
70 | |||
71 | return true; | ||
60 | } | 72 | } |
61 | 73 | ||
62 | static void update(IsoGfx* iso, void* app_state, double t, double dt) { | 74 | static void shutdown(IsoGfxAppState* state, IsoGfx* iso) { |
75 | assert(state); | ||
76 | assert(iso); | ||
77 | } | ||
78 | |||
79 | static void update(IsoGfxAppState* state, IsoGfx* iso, double t, double dt) { | ||
80 | assert(state); | ||
63 | assert(iso); | 81 | assert(iso); |
64 | assert(app_state); | ||
65 | State* state = (State*)(app_state); | ||
66 | 82 | ||
67 | double mouse_x, mouse_y; | 83 | double mouse_x, mouse_y; |
68 | gfx_app_get_mouse_position(&mouse_x, &mouse_y); | 84 | gfx_app_get_mouse_position(&mouse_x, &mouse_y); |
@@ -72,49 +88,27 @@ static void update(IsoGfx* iso, void* app_state, double t, double dt) { | |||
72 | printf("Picked tile: (%d, %d)\n", state->xpick, state->ypick); | 88 | printf("Picked tile: (%d, %d)\n", state->xpick, state->ypick); |
73 | } | 89 | } |
74 | 90 | ||
75 | static void render(IsoGfx* iso, void* app_state) { | 91 | static void render(IsoGfxAppState* state, IsoGfx* iso) { |
92 | assert(state); | ||
76 | assert(iso); | 93 | assert(iso); |
77 | assert(app_state); | ||
78 | State* state = (State*)(app_state); | ||
79 | 94 | ||
80 | isogfx_render(iso); | 95 | isogfx_render(iso); |
96 | |||
81 | if ((state->xpick != -1) && (state->ypick != -1)) { | 97 | if ((state->xpick != -1) && (state->ypick != -1)) { |
82 | isogfx_draw_tile(iso, state->xpick, state->ypick, state->red); | 98 | isogfx_draw_tile(iso, state->xpick, state->ypick, state->red); |
83 | } | 99 | } |
84 | } | 100 | } |
85 | 101 | ||
86 | bool make_checkerboard_app(IsoGfx* iso, IsoGfxApp* app) { | 102 | int main(int argc, const char** argv) { |
87 | assert(iso); | 103 | IsoGfxAppState state = {0}; |
88 | assert(app); | 104 | iso_run( |
89 | 105 | argc, argv, | |
90 | State* state = calloc(1, sizeof(State)); | 106 | &(IsoGfxApp){ |
91 | if (!state) { | 107 | .state = &state, |
92 | return false; | 108 | .init = init, |
93 | } | 109 | .shutdown = shutdown, |
94 | 110 | .update = update, | |
95 | if (!isogfx_make_world( | 111 | .render = render, |
96 | iso, &(WorldDesc){ | 112 | }); |
97 | .tile_width = TILE_WIDTH, | 113 | return 0; |
98 | .tile_height = TILE_HEIGHT, | ||
99 | .world_width = WORLD_WIDTH, | ||
100 | .world_height = WORLD_HEIGHT})) { | ||
101 | goto cleanup; | ||
102 | } | ||
103 | |||
104 | const Tile black = isogfx_make_tile(iso, &tile_set[Black]); | ||
105 | const Tile white = isogfx_make_tile(iso, &tile_set[White]); | ||
106 | state->red = isogfx_make_tile(iso, &tile_set[Red]); | ||
107 | make_checkerboard(iso, black, white); | ||
108 | isogfx_render(iso); | ||
109 | |||
110 | app->state = state; | ||
111 | app->shutdown = shutdown; | ||
112 | app->update = update; | ||
113 | app->render = render; | ||
114 | |||
115 | return true; | ||
116 | |||
117 | cleanup: | ||
118 | free(state); | ||
119 | return false; | ||
120 | } | 114 | } |
diff --git a/gfx-iso/demos/isomap/CMakeLists.txt b/gfx-iso/demos/isomap/CMakeLists.txt new file mode 100644 index 0000000..13edcc7 --- /dev/null +++ b/gfx-iso/demos/isomap/CMakeLists.txt | |||
@@ -0,0 +1,15 @@ | |||
1 | cmake_minimum_required(VERSION 3.0) | ||
2 | |||
3 | project(isomap) | ||
4 | |||
5 | set(CMAKE_C_STANDARD 17) | ||
6 | set(CMAKE_C_STANDARD_REQUIRED On) | ||
7 | set(CMAKE_C_EXTENSIONS Off) | ||
8 | |||
9 | add_executable(isomap | ||
10 | isomap.c) | ||
11 | |||
12 | target_link_libraries(isomap PRIVATE | ||
13 | isogfx-app) | ||
14 | |||
15 | target_compile_options(isomap PRIVATE -Wall -Wextra -Wpedantic) | ||
diff --git a/gfx-iso/app/isogfx-demo.c b/gfx-iso/demos/isomap/isomap.c index 9889275..d204d28 100644 --- a/gfx-iso/app/isogfx-demo.c +++ b/gfx-iso/demos/isomap/isomap.c | |||
@@ -1,31 +1,45 @@ | |||
1 | #include "isogfx-demo.h" | 1 | #include <isogfx/app.h> |
2 | |||
3 | #include <gfx/gfx_app.h> | ||
4 | #include <isogfx/isogfx.h> | 2 | #include <isogfx/isogfx.h> |
5 | 3 | ||
6 | #include <assert.h> | 4 | #include <assert.h> |
7 | #include <stdbool.h> | 5 | #include <stdbool.h> |
8 | #include <stdio.h> | ||
9 | #include <stdlib.h> | ||
10 | 6 | ||
11 | typedef struct State { | 7 | typedef struct IsoGfxAppState { |
12 | int xpick; | 8 | int xpick; |
13 | int ypick; | 9 | int ypick; |
14 | SpriteSheet stag_sheet; | 10 | SpriteSheet stag_sheet; |
15 | Sprite stag; | 11 | Sprite stag; |
16 | } State; | 12 | } IsoGfxAppState; |
17 | 13 | ||
18 | static void shutdown(IsoGfx* iso, void* app_state) { | 14 | static bool init( |
15 | IsoGfxAppState* state, IsoGfx* iso, int argc, const char** argv) { | ||
16 | assert(state); | ||
19 | assert(iso); | 17 | assert(iso); |
20 | if (app_state) { | 18 | |
21 | free(app_state); | 19 | if (!isogfx_load_world(iso, "/home/jeanne/assets/tilemaps/demo1.tm")) { |
20 | return false; | ||
21 | } | ||
22 | |||
23 | if (!isogfx_load_sprite_sheet( | ||
24 | iso, "/home/jeanne/assets/tilesets/scrabling/critters/stag/stag.ss", | ||
25 | &state->stag_sheet)) { | ||
26 | return false; | ||
22 | } | 27 | } |
28 | |||
29 | state->stag = isogfx_make_sprite(iso, state->stag_sheet); | ||
30 | isogfx_set_sprite_position(iso, state->stag, 5, 4); | ||
31 | |||
32 | return true; | ||
23 | } | 33 | } |
24 | 34 | ||
25 | static void update(IsoGfx* iso, void* app_state, double t, double dt) { | 35 | static void shutdown(IsoGfxAppState* state, IsoGfx* iso) { |
36 | assert(state); | ||
37 | assert(iso); | ||
38 | } | ||
39 | |||
40 | static void update(IsoGfxAppState* state, IsoGfx* iso, double t, double dt) { | ||
41 | assert(state); | ||
26 | assert(iso); | 42 | assert(iso); |
27 | assert(app_state); | ||
28 | State* state = (State*)(app_state); | ||
29 | 43 | ||
30 | double mouse_x, mouse_y; | 44 | double mouse_x, mouse_y; |
31 | gfx_app_get_mouse_position(&mouse_x, &mouse_y); | 45 | gfx_app_get_mouse_position(&mouse_x, &mouse_y); |
@@ -35,45 +49,24 @@ static void update(IsoGfx* iso, void* app_state, double t, double dt) { | |||
35 | // printf("Picked tile: (%d, %d)\n", state->xpick, state->ypick); | 49 | // printf("Picked tile: (%d, %d)\n", state->xpick, state->ypick); |
36 | } | 50 | } |
37 | 51 | ||
38 | static void render(IsoGfx* iso, void* app_state) { | 52 | static void render(IsoGfxAppState* state, IsoGfx* iso) { |
53 | assert(state); | ||
39 | assert(iso); | 54 | assert(iso); |
40 | assert(app_state); | ||
41 | State* state = (State*)(app_state); | ||
42 | 55 | ||
43 | isogfx_render(iso); | 56 | isogfx_render(iso); |
44 | } | 57 | } |
45 | 58 | ||
46 | bool make_demo_app(IsoGfx* iso, IsoGfxApp* app) { | 59 | int main(int argc, const char** argv) { |
47 | assert(iso); | 60 | IsoGfxAppState state = {0}; |
48 | assert(app); | 61 | iso_run( |
49 | 62 | argc, argv, | |
50 | State* state = calloc(1, sizeof(State)); | 63 | &(IsoGfxApp){ |
51 | if (!state) { | 64 | .pixel_scale = 2, |
52 | return false; | 65 | .state = &state, |
53 | } | 66 | .init = init, |
54 | 67 | .shutdown = shutdown, | |
55 | if (!isogfx_load_world(iso, "/home/jeanne/assets/tilemaps/demo1.tm")) { | 68 | .update = update, |
56 | goto cleanup; | 69 | .render = render, |
57 | } | 70 | }); |
58 | 71 | return 0; | |
59 | if (!isogfx_load_sprite_sheet( | ||
60 | iso, "/home/jeanne/assets/tilesets/scrabling/critters/stag/stag.ss", | ||
61 | &state->stag_sheet)) { | ||
62 | goto cleanup; | ||
63 | } | ||
64 | |||
65 | state->stag = isogfx_make_sprite(iso, state->stag_sheet); | ||
66 | isogfx_set_sprite_position(iso, state->stag, 5, 4); | ||
67 | |||
68 | app->pixel_scale = 2; | ||
69 | app->state = state; | ||
70 | app->shutdown = shutdown; | ||
71 | app->update = update; | ||
72 | app->render = render; | ||
73 | |||
74 | return true; | ||
75 | |||
76 | cleanup: | ||
77 | free(state); | ||
78 | return false; | ||
79 | } | 72 | } |
diff --git a/gfx-iso/include/isogfx/app.h b/gfx-iso/include/isogfx/app.h new file mode 100644 index 0000000..0a0fcc1 --- /dev/null +++ b/gfx-iso/include/isogfx/app.h | |||
@@ -0,0 +1,22 @@ | |||
1 | #pragma once | ||
2 | |||
3 | #include <gfx/gfx_app.h> | ||
4 | |||
5 | #include <stdbool.h> | ||
6 | |||
7 | typedef struct IsoGfx IsoGfx; | ||
8 | typedef struct IsoGfxApp IsoGfxApp; | ||
9 | |||
10 | typedef struct IsoGfxAppState IsoGfxAppState; | ||
11 | |||
12 | typedef struct IsoGfxApp { | ||
13 | int pixel_scale; // 0 or 1 for 1:1 scale. | ||
14 | IsoGfxAppState* state; | ||
15 | |||
16 | bool (*init)(IsoGfxAppState*, IsoGfx*, int argc, const char** argv); | ||
17 | void (*shutdown)(IsoGfxAppState*, IsoGfx*); | ||
18 | void (*update)(IsoGfxAppState*, IsoGfx*, double t, double dt); | ||
19 | void (*render)(IsoGfxAppState*, IsoGfx*); | ||
20 | } IsoGfxApp; | ||
21 | |||
22 | void iso_run(int argc, const char** argv, IsoGfxApp*); | ||
diff --git a/gfx-iso/app/main.c b/gfx-iso/src/app.c index 050a42f..079ac96 100644 --- a/gfx-iso/app/main.c +++ b/gfx-iso/src/app.c | |||
@@ -1,7 +1,4 @@ | |||
1 | #include "app.h" | 1 | #include <isogfx/app.h> |
2 | #include "checkerboard.h" | ||
3 | #include "isogfx-demo.h" | ||
4 | |||
5 | #include <isogfx/isogfx.h> | 2 | #include <isogfx/isogfx.h> |
6 | 3 | ||
7 | #include <gfx/gfx.h> | 4 | #include <gfx/gfx.h> |
@@ -18,37 +15,40 @@ | |||
18 | 15 | ||
19 | static const int SCREEN_WIDTH = 1408; | 16 | static const int SCREEN_WIDTH = 1408; |
20 | static const int SCREEN_HEIGHT = 960; | 17 | static const int SCREEN_HEIGHT = 960; |
18 | static const int MAX_FPS = 60; | ||
21 | 19 | ||
22 | typedef struct State { | 20 | typedef struct AppState { |
23 | Gfx* gfx; | 21 | Gfx* gfx; |
24 | IsoGfx* iso; | 22 | IsoGfx* iso; |
25 | IsoGfxApp app; | 23 | IsoGfxApp* app; |
26 | Texture* screen_texture; | 24 | Texture* screen_texture; |
27 | Scene* scene; | 25 | Scene* scene; |
28 | } State; | 26 | } AppState; |
29 | 27 | ||
30 | static bool init(const GfxAppDesc* desc, void** app_state) { | 28 | typedef struct GfxAppState { |
31 | State* state = calloc(1, sizeof(State)); | 29 | AppState state; |
32 | if (!state) { | 30 | } GfxAppState; |
33 | return false; | 31 | |
34 | } | 32 | static bool init(GfxAppState* gfx_app_state, int argc, const char** argv) { |
33 | assert(gfx_app_state); | ||
34 | AppState* state = &gfx_app_state->state; | ||
35 | |||
36 | IsoGfxApp* app = state->app; | ||
35 | 37 | ||
36 | if (!(state->iso = isogfx_new(&(IsoGfxDesc){ | 38 | if (!(state->iso = isogfx_new(&(IsoGfxDesc){ |
37 | .screen_width = SCREEN_WIDTH, .screen_height = SCREEN_HEIGHT}))) { | 39 | .screen_width = SCREEN_WIDTH, .screen_height = SCREEN_HEIGHT}))) { |
38 | goto cleanup; | 40 | goto cleanup; |
39 | } | 41 | } |
40 | // if (!make_checkerboard_app(state->iso, &state->app)) { | 42 | |
41 | // goto cleanup; | 43 | if (!(*app->init)(app->state, state->iso, argc, argv)) { |
42 | // } | ||
43 | if (!make_demo_app(state->iso, &state->app)) { | ||
44 | goto cleanup; | 44 | goto cleanup; |
45 | } | 45 | } |
46 | 46 | ||
47 | // Apply pixel scaling if requested by the app. | 47 | // Apply pixel scaling if requested by the app. |
48 | int texture_width, texture_height; | 48 | int texture_width, texture_height; |
49 | if (state->app.pixel_scale > 1) { | 49 | if (app->pixel_scale > 1) { |
50 | texture_width = SCREEN_WIDTH / state->app.pixel_scale; | 50 | texture_width = SCREEN_WIDTH / app->pixel_scale; |
51 | texture_height = SCREEN_HEIGHT / state->app.pixel_scale; | 51 | texture_height = SCREEN_HEIGHT / app->pixel_scale; |
52 | isogfx_resize(state->iso, texture_width, texture_height); | 52 | isogfx_resize(state->iso, texture_width, texture_height); |
53 | } else { | 53 | } else { |
54 | texture_width = SCREEN_WIDTH; | 54 | texture_width = SCREEN_WIDTH; |
@@ -110,7 +110,6 @@ static bool init(const GfxAppDesc* desc, void** app_state) { | |||
110 | SceneNode* root = gfx_get_scene_root(state->scene); | 110 | SceneNode* root = gfx_get_scene_root(state->scene); |
111 | gfx_set_node_parent(node, root); | 111 | gfx_set_node_parent(node, root); |
112 | 112 | ||
113 | *app_state = state; | ||
114 | return true; | 113 | return true; |
115 | 114 | ||
116 | cleanup: | 115 | cleanup: |
@@ -121,35 +120,35 @@ cleanup: | |||
121 | return false; | 120 | return false; |
122 | } | 121 | } |
123 | 122 | ||
124 | static void shutdown(void* app_state) { | 123 | static void shutdown(GfxAppState* gfx_app_state) { |
125 | assert(app_state); | 124 | assert(gfx_app_state); |
126 | State* state = (State*)(app_state); | 125 | AppState* state = &gfx_app_state->state; |
127 | 126 | ||
128 | if (state->app.state) { | 127 | if (state->app) { |
129 | assert(state->iso); | 128 | assert(state->iso); |
130 | (*state->app.shutdown)(state->iso, state->app.state); | 129 | (*state->app->shutdown)(state->app->state, state->iso); |
131 | } | 130 | } |
131 | |||
132 | isogfx_del(&state->iso); | 132 | isogfx_del(&state->iso); |
133 | gfx_destroy(&state->gfx); | 133 | gfx_destroy(&state->gfx); |
134 | free(app_state); | ||
135 | } | 134 | } |
136 | 135 | ||
137 | static void update(void* app_state, double t, double dt) { | 136 | static void update(GfxAppState* gfx_app_state, double t, double dt) { |
138 | assert(app_state); | 137 | assert(gfx_app_state); |
139 | State* state = (State*)(app_state); | 138 | AppState* state = &gfx_app_state->state; |
140 | 139 | ||
141 | isogfx_update(state->iso, t); | 140 | isogfx_update(state->iso, t); |
142 | 141 | ||
143 | assert(state->app.update); | 142 | assert(state->app->update); |
144 | (*state->app.update)(state->iso, state->app.state, t, dt); | 143 | (*state->app->update)(state->app->state, state->iso, t, dt); |
145 | } | 144 | } |
146 | 145 | ||
147 | static void render(void* app_state) { | 146 | static void render(GfxAppState* gfx_app_state) { |
148 | assert(app_state); | 147 | assert(gfx_app_state); |
149 | State* state = (State*)(app_state); | 148 | AppState* state = &gfx_app_state->state; |
150 | 149 | ||
151 | assert(state->app.render); | 150 | assert(state->app->render); |
152 | (*state->app.render)(state->iso, state->app.state); | 151 | (*state->app->render)(state->app->state, state->iso); |
153 | 152 | ||
154 | const Pixel* screen = isogfx_get_screen_buffer(state->iso); | 153 | const Pixel* screen = isogfx_get_screen_buffer(state->iso); |
155 | assert(screen); | 154 | assert(screen); |
@@ -166,34 +165,34 @@ static void render(void* app_state) { | |||
166 | gfx_end_frame(render_backend); | 165 | gfx_end_frame(render_backend); |
167 | } | 166 | } |
168 | 167 | ||
169 | static void resize(void* app_state, int width, int height) { | 168 | static void resize(GfxAppState* gfx_app_state, int width, int height) { |
170 | assert(app_state); | 169 | assert(gfx_app_state); |
171 | State* state = (State*)(app_state); | 170 | AppState* state = &gfx_app_state->state; |
172 | 171 | ||
173 | RenderBackend* render_backend = gfx_get_render_backend(state->gfx); | 172 | RenderBackend* render_backend = gfx_get_render_backend(state->gfx); |
174 | gfx_set_viewport(render_backend, width, height); | 173 | gfx_set_viewport(render_backend, width, height); |
175 | } | 174 | } |
176 | 175 | ||
177 | int main(int argc, const char** argv) { | 176 | void iso_run(int argc, const char** argv, IsoGfxApp* app) { |
178 | const int initial_width = SCREEN_WIDTH; | 177 | GfxAppState app_state = { |
179 | const int initial_height = SCREEN_HEIGHT; | 178 | .state = (AppState){ |
180 | const int max_fps = 60; | 179 | .app = app, |
181 | 180 | } | |
181 | }; | ||
182 | gfx_app_run( | 182 | gfx_app_run( |
183 | &(GfxAppDesc){ | 183 | &(GfxAppDesc){ |
184 | .argc = argc, | 184 | .argc = argc, |
185 | .argv = argv, | 185 | .argv = argv, |
186 | .width = initial_width, | 186 | .width = SCREEN_WIDTH, |
187 | .height = initial_height, | 187 | .height = SCREEN_HEIGHT, |
188 | .max_fps = max_fps, | 188 | .max_fps = MAX_FPS, |
189 | .update_delta_time = max_fps > 0 ? 1.0 / (double)max_fps : 0.0, | 189 | .update_delta_time = MAX_FPS > 0 ? 1.0 / (double)MAX_FPS : 0.0, |
190 | .title = "Isometric Renderer"}, | 190 | .title = "Isometric Renderer", |
191 | .app_state = &app_state}, | ||
191 | &(GfxAppCallbacks){ | 192 | &(GfxAppCallbacks){ |
192 | .init = init, | 193 | .init = init, |
193 | .update = update, | 194 | .update = update, |
194 | .render = render, | 195 | .render = render, |
195 | .resize = resize, | 196 | .resize = resize, |
196 | .shutdown = shutdown}); | 197 | .shutdown = shutdown}); |
197 | |||
198 | return 0; | ||
199 | } | 198 | } |
diff --git a/gfx-iso/asset/mkasset.py b/gfx-iso/tools/mkasset.py index 3ca8a1d..3ca8a1d 100644 --- a/gfx-iso/asset/mkasset.py +++ b/gfx-iso/tools/mkasset.py | |||