#include #include #include #include #include #include #include static const int WINDOW_WIDTH = 1408; static const int WINDOW_HEIGHT = 960; static const int MAX_FPS = 60; // Virtual screen dimensions. static const int SCREEN_WIDTH = 704; static const int SCREEN_HEIGHT = 480; static const R CAMERA_SPEED = 800; #define MEMORY_SIZE (8 * 1024 * 1024) uint8_t MEMORY[MEMORY_SIZE]; typedef struct GfxAppState { Gfx2dBackend* backend; Gfx2d* gfx; int xpick; int ypick; vec2 camera; SpriteSheet stag_sheet; Sprite stag; } GfxAppState; static bool init(GfxApp* app, GfxAppState* state, int argc, const char** argv) { assert(app); assert(state); (void)argc; (void)argv; if (!((state->gfx = gfx2d_new(&(Gfx2dDesc){.memory = MEMORY, .memory_size = MEMORY_SIZE, .screen_width = SCREEN_WIDTH, .screen_height = SCREEN_HEIGHT})))) { return false; } Gfx2d* iso = state->gfx; if (!gfx2d_load_map( iso, "/home/jeanne/Nextcloud/assets/tilemaps/scrabling1.tm")) { return false; } if (!((state->stag_sheet = gfx2d_load_sprite_sheet( iso, "/home/jeanne/Nextcloud/assets/tilesets/scrabling/critters/stag/" "stag.ss")))) { return false; } state->stag = gfx2d_make_sprite(iso, state->stag_sheet); gfx2d_set_sprite_position(iso, state->stag, 0, 0); if (!((state->backend = gfx2d_backend_init(iso)))) { return false; } return true; } static void shutdown(GfxApp* app, GfxAppState* state) { assert(app); assert(state); } static vec2 get_camera_movement(GfxApp* app, R dt) { assert(app); vec2 offset = {0}; if (gfx_app_is_key_pressed(app, KeyA)) { offset.x -= 1; } if (gfx_app_is_key_pressed(app, KeyD)) { offset.x += 1; } if (gfx_app_is_key_pressed(app, KeyW)) { offset.y -= 1; } if (gfx_app_is_key_pressed(app, KeyS)) { offset.y += 1; } if ((offset.x != 0) || (offset.y != 0)) { offset = vec2_scale(vec2_normalize(offset), dt * CAMERA_SPEED); } return offset; } static void update(GfxApp* app, GfxAppState* state, double t, double dt) { assert(app); assert(state); state->camera = vec2_add(state->camera, get_camera_movement(app, (R)dt)); Gfx2d* iso = state->gfx; gfx2d_set_camera(iso, (int)state->camera.x, (int)state->camera.y); gfx2d_update(iso, t); } static void render(const GfxApp* app, GfxAppState* state) { assert(app); assert(state); Gfx2d* iso = state->gfx; gfx2d_render(iso); gfx2d_backend_render(state->backend, iso); } static void resize(GfxApp* app, GfxAppState* state, int width, int height) { assert(app); assert(state); gfx2d_backend_resize_window(state->backend, state->gfx, width, height); } int main(int argc, const char** argv) { GfxAppState state = {0}; gfx_app_run( &(GfxAppDesc){.argc = argc, .argv = argv, .width = WINDOW_WIDTH, .height = WINDOW_HEIGHT, .max_fps = MAX_FPS, .update_delta_time = MAX_FPS > 0 ? 1.0 / (double)MAX_FPS : 0.0, .title = "Isometric Renderer", .app_state = &state}, &(GfxAppCallbacks){.init = init, .update = update, .render = render, .resize = resize, .shutdown = shutdown}); return 0; }