summaryrefslogtreecommitdiff
path: root/gfx-iso
diff options
context:
space:
mode:
author3gg <3gg@shellblade.net>2024-03-09 08:43:26 -0800
committer3gg <3gg@shellblade.net>2024-03-09 08:43:26 -0800
commitadbd2511beec8f1caa1752bdfd755cc2f62ba425 (patch)
tree8fde167e9d9951b43e571a2417ae55f9572bea28 /gfx-iso
parent4bc4ca2796bd434880b77d3c4bcbb56107456777 (diff)
Make isogfx a library instead of an executable.
Diffstat (limited to 'gfx-iso')
-rw-r--r--gfx-iso/CMakeLists.txt29
-rw-r--r--gfx-iso/app/app.h12
-rw-r--r--gfx-iso/app/checkerboard.h9
-rw-r--r--gfx-iso/app/isogfx-demo.h9
-rw-r--r--gfx-iso/demos/CMakeLists.txt2
-rw-r--r--gfx-iso/demos/checkerboard/CMakeLists.txt15
-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.txt15
-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.h22
-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
12 files changed, 213 insertions, 194 deletions
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
3project(isogfx) 3project(isogfx)
4 4
5set(CMAKE_C_STANDARD 11) 5set(CMAKE_C_STANDARD 17)
6set(CMAKE_C_STANDARD_REQUIRED On) 6set(CMAKE_C_STANDARD_REQUIRED On)
7set(CMAKE_C_EXTENSIONS Off) 7set(CMAKE_C_EXTENSIONS Off)
8 8
9# isogfx
10
9add_library(isogfx 11add_library(isogfx
10 src/isogfx.c) 12 src/isogfx.c)
11 13
12target_include_directories(isogfx PUBLIC 14target_include_directories(isogfx PUBLIC
13 include) 15 include)
14 16
15target_link_libraries(isogfx PRIVATE 17target_link_libraries(isogfx PUBLIC
16 filesystem 18 filesystem
17 mem 19 mem
18 mempool) 20 mempool)
19 21
20target_compile_options(isogfx PRIVATE -Wall -Wextra -Wpedantic) 22target_compile_options(isogfx PRIVATE -Wall -Wextra -Wpedantic)
21 23
22# Demo 24# App
23 25
24project(isogfx-app) 26add_library(isogfx-app
27 src/app.c)
25 28
26add_executable(isogfx-app 29target_include_directories(isogfx-app PUBLIC
27 app/checkerboard.c 30 include)
28 app/isogfx-demo.c
29 app/main.c)
30 31
31target_link_libraries(isogfx-app PRIVATE 32target_link_libraries(isogfx-app PUBLIC
32 gfx
33 gfx-app 33 gfx-app
34 isogfx) 34 isogfx)
35
36target_link_libraries(isogfx-app PRIVATE
37 gfx)
38
39target_compile_options(isogfx-app PRIVATE -Wall -Wextra -Wpedantic)
40
41# Demos
42
43add_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
3typedef struct IsoGfx IsoGfx;
4typedef struct IsoGfxApp IsoGfxApp;
5
6typedef 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
7typedef struct IsoGfxApp IsoGfxApp;
8
9bool 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
7typedef struct IsoGfxApp IsoGfxApp;
8
9bool 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 @@
1add_subdirectory(checkerboard)
2add_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 @@
1cmake_minimum_required(VERSION 3.0)
2
3project(checkerboard)
4
5set(CMAKE_C_STANDARD 17)
6set(CMAKE_C_STANDARD_REQUIRED On)
7set(CMAKE_C_EXTENSIONS Off)
8
9add_executable(checkerboard
10 checkerboard.c)
11
12target_link_libraries(checkerboard PRIVATE
13 isogfx-app)
14
15target_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
11static const int TILE_WIDTH = 64; 8static const int TILE_WIDTH = 64;
12static const int TILE_HEIGHT = TILE_WIDTH / 2; 9static const int TILE_HEIGHT = TILE_WIDTH / 2;
@@ -34,11 +31,11 @@ typedef enum Colour {
34 Red, 31 Red,
35} Colour; 32} Colour;
36 33
37typedef struct State { 34typedef 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
43static void make_checkerboard(IsoGfx* iso, Tile black, Tile white) { 40static 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
55static void shutdown(IsoGfx* iso, void* app_state) { 52static 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
62static void update(IsoGfx* iso, void* app_state, double t, double dt) { 74static void shutdown(IsoGfxAppState* state, IsoGfx* iso) {
75 assert(state);
76 assert(iso);
77}
78
79static 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
75static void render(IsoGfx* iso, void* app_state) { 91static 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
86bool make_checkerboard_app(IsoGfx* iso, IsoGfxApp* app) { 102int 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
117cleanup:
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 @@
1cmake_minimum_required(VERSION 3.0)
2
3project(isomap)
4
5set(CMAKE_C_STANDARD 17)
6set(CMAKE_C_STANDARD_REQUIRED On)
7set(CMAKE_C_EXTENSIONS Off)
8
9add_executable(isomap
10 isomap.c)
11
12target_link_libraries(isomap PRIVATE
13 isogfx-app)
14
15target_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
11typedef struct State { 7typedef 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
18static void shutdown(IsoGfx* iso, void* app_state) { 14static 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
25static void update(IsoGfx* iso, void* app_state, double t, double dt) { 35static void shutdown(IsoGfxAppState* state, IsoGfx* iso) {
36 assert(state);
37 assert(iso);
38}
39
40static 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
38static void render(IsoGfx* iso, void* app_state) { 52static 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
46bool make_demo_app(IsoGfx* iso, IsoGfxApp* app) { 59int 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
76cleanup:
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
7typedef struct IsoGfx IsoGfx;
8typedef struct IsoGfxApp IsoGfxApp;
9
10typedef struct IsoGfxAppState IsoGfxAppState;
11
12typedef 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
22void 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
19static const int SCREEN_WIDTH = 1408; 16static const int SCREEN_WIDTH = 1408;
20static const int SCREEN_HEIGHT = 960; 17static const int SCREEN_HEIGHT = 960;
18static const int MAX_FPS = 60;
21 19
22typedef struct State { 20typedef 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
30static bool init(const GfxAppDesc* desc, void** app_state) { 28typedef struct GfxAppState {
31 State* state = calloc(1, sizeof(State)); 29 AppState state;
32 if (!state) { 30} GfxAppState;
33 return false; 31
34 } 32static 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
116cleanup: 115cleanup:
@@ -121,35 +120,35 @@ cleanup:
121 return false; 120 return false;
122} 121}
123 122
124static void shutdown(void* app_state) { 123static 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
137static void update(void* app_state, double t, double dt) { 136static 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
147static void render(void* app_state) { 146static 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
169static void resize(void* app_state, int width, int height) { 168static 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
177int main(int argc, const char** argv) { 176void 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