From 4fd6b58064bd26df93b05e39438dab649a65633c Mon Sep 17 00:00:00 2001
From: 3gg <3gg@shellblade.net>
Date: Sat, 8 Jul 2023 15:03:05 -0700
Subject: Add pixel scaling.

---
 gfx-iso/app/app.h               |  1 +
 gfx-iso/app/isogfx-demo.c       |  9 +++++----
 gfx-iso/app/main.c              | 16 ++++++++++++++--
 gfx-iso/include/isogfx/isogfx.h |  5 ++++-
 gfx-iso/src/isogfx.c            | 21 +++++++++++++++++++++
 5 files changed, 45 insertions(+), 7 deletions(-)

diff --git a/gfx-iso/app/app.h b/gfx-iso/app/app.h
index 160da47..25e55eb 100644
--- a/gfx-iso/app/app.h
+++ b/gfx-iso/app/app.h
@@ -4,6 +4,7 @@ typedef struct IsoGfx    IsoGfx;
 typedef struct IsoGfxApp IsoGfxApp;
 
 typedef struct IsoGfxApp {
+  int   pixel_scale; // 0 or 1 for 1:1 scale.
   void* state;
   void (*shutdown)(IsoGfx*, void* state);
   void (*update)(IsoGfx*, void* state, double t, double dt);
diff --git a/gfx-iso/app/isogfx-demo.c b/gfx-iso/app/isogfx-demo.c
index 15ab6be..d463d1c 100644
--- a/gfx-iso/app/isogfx-demo.c
+++ b/gfx-iso/app/isogfx-demo.c
@@ -54,10 +54,11 @@ bool make_demo_app(IsoGfx* iso, IsoGfxApp* app) {
     goto cleanup;
   }
 
-  app->state    = state;
-  app->shutdown = shutdown;
-  app->update   = update;
-  app->render   = render;
+  app->pixel_scale = 2;
+  app->state       = state;
+  app->shutdown    = shutdown;
+  app->update      = update;
+  app->render      = render;
 
   return true;
 
diff --git a/gfx-iso/app/main.c b/gfx-iso/app/main.c
index fa5a76b..5b441d3 100644
--- a/gfx-iso/app/main.c
+++ b/gfx-iso/app/main.c
@@ -43,6 +43,18 @@ static bool init(const GfxAppDesc* desc, void** app_state) {
   if (!make_demo_app(state->iso, &state->app)) {
     goto cleanup;
   }
+
+  // Apply pixel scaling if requested by the app.
+  int texture_width, texture_height;
+  if (state->app.pixel_scale > 1) {
+    texture_width  = SCREEN_WIDTH / state->app.pixel_scale;
+    texture_height = SCREEN_HEIGHT / state->app.pixel_scale;
+    isogfx_resize(state->iso, texture_width, texture_height);
+  } else {
+    texture_width  = SCREEN_WIDTH;
+    texture_height = SCREEN_HEIGHT;
+  }
+
   if (!(state->gfx = gfx_init())) {
     goto cleanup;
   }
@@ -50,8 +62,8 @@ static bool init(const GfxAppDesc* desc, void** app_state) {
 
   if (!(state->screen_texture = gfx_make_texture(
             render_backend, &(TextureDesc){
-                                .width     = SCREEN_WIDTH,
-                                .height    = SCREEN_HEIGHT,
+                                .width     = texture_width,
+                                .height    = texture_height,
                                 .dimension = Texture2D,
                                 .format    = TextureSRGBA8,
                                 .filtering = NearestFiltering,
diff --git a/gfx-iso/include/isogfx/isogfx.h b/gfx-iso/include/isogfx/isogfx.h
index 22c8fd5..5c44310 100644
--- a/gfx-iso/include/isogfx/isogfx.h
+++ b/gfx-iso/include/isogfx/isogfx.h
@@ -93,7 +93,10 @@ void isogfx_render(IsoGfx*);
 /// position (x,y) instead, use isogfx_set_tile().
 void isogfx_draw_tile(IsoGfx*, int x, int y, Tile);
 
-/// Return a pointer to the internal colour buffer.
+/// Resize the virtual screen's dimensions.
+bool isogfx_resize(IsoGfx*, int screen_width, int screen_height);
+
+/// Return a pointer to the virtual screen's colour buffer.
 ///
 /// Call after each call to isogfx_render() to retrieve the render output.
 const Pixel* isogfx_get_screen_buffer(const IsoGfx*);
diff --git a/gfx-iso/src/isogfx.c b/gfx-iso/src/isogfx.c
index 17b88b2..ee33cad 100644
--- a/gfx-iso/src/isogfx.c
+++ b/gfx-iso/src/isogfx.c
@@ -603,6 +603,27 @@ void isogfx_draw_tile(IsoGfx* iso, int x, int y, Tile tile) {
   draw_tile(iso, so, tile);
 }
 
+bool isogfx_resize(IsoGfx* iso, int screen_width, int screen_height) {
+  assert(iso);
+  assert(iso->screen);
+
+  const int current_size = iso->screen_width * iso->screen_height;
+  const int new_size     = screen_width * screen_height;
+
+  if (new_size > current_size) {
+    Pixel* new_screen = calloc(new_size, sizeof(Pixel));
+    if (new_screen) {
+      free(iso->screen);
+      iso->screen = new_screen;
+    } else {
+      return false;
+    }
+  }
+  iso->screen_width  = screen_width;
+  iso->screen_height = screen_height;
+  return true;
+}
+
 const Pixel* isogfx_get_screen_buffer(const IsoGfx* iso) {
   assert(iso);
   return iso->screen;
-- 
cgit v1.2.3