summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKonAki <konaki@anokonaki.org>2026-10-12 13:54:29 +0800
committerKonAki <konaki@anokonaki.org>2026-10-12 13:54:29 +0800
commitd5cdd33e46c8646fe48f3a31f30dbd90c69e823c (patch)
tree11d6af1003dc9b8454e6356f8ed82936d885f978
parentad3144d68642d02782c10df688dd1a5340d8c091 (diff)
stage: scale x and y, rotation, blend mode and colour per sprite
-rw-r--r--kon/konstage.c38
-rw-r--r--kon/konstage.h12
2 files changed, 37 insertions, 13 deletions
diff --git a/kon/konstage.c b/kon/konstage.c
index 1b958be..8566a3f 100644
--- a/kon/konstage.c
+++ b/kon/konstage.c
@@ -33,9 +33,9 @@ static int valid(const kon_stage_t *stage, int index)
return index >= 0 && index < stage->capacity && stage->sprites[index].used;
}
-static uint32_t tintOf(float alpha, float brightness)
+static uint32_t tintOf(float alpha, float brightness, uint32_t color)
{
- uint32_t a, b;
+ uint32_t a, b, r, g, bl;
if (!(alpha > 0.0f)) alpha = 0.0f;
if (alpha > 1.0f) alpha = 1.0f;
@@ -43,7 +43,10 @@ static uint32_t tintOf(float alpha, float brightness)
if (brightness > 1.0f) brightness = 1.0f;
a = (uint32_t)(alpha * 255.0f + 0.5f);
b = (uint32_t)(brightness * 255.0f + 0.5f);
- return (a << 24) | (b << 16) | (b << 8) | b;
+ r = (b * ((color >> 16) & 0xFF) + 127) / 255;
+ g = (b * ((color >> 8) & 0xFF) + 127) / 255;
+ bl = (b * (color & 0xFF) + 127) / 255;
+ return (a << 24) | (r << 16) | (g << 8) | bl;
}
static kon_rect_t wholeOf(const kon_image *image, const kon_rect_t *src)
@@ -130,9 +133,11 @@ int kon_stageAdd(kon_stage_t *stage, const kon_image *image, const kon_rect_t *s
s->src = wholeOf(image, src);
s->anchorX = 0.5f;
s->anchorY = 1.0f;
+ s->color = 0xFFFFFFFFu;
s->layer = layer;
for (p = 0; p < KON_PROP_COUNT; p++) kon_tweenSet(&s->prop[p], 0.0f);
- kon_tweenSet(&s->prop[KON_PROP_SCALE], 1.0f);
+ kon_tweenSet(&s->prop[KON_PROP_SCALE_X], 1.0f);
+ kon_tweenSet(&s->prop[KON_PROP_SCALE_Y], 1.0f);
kon_tweenSet(&s->prop[KON_PROP_BRIGHTNESS], 1.0f);
return i;
}
@@ -162,6 +167,17 @@ void kon_stageTween(kon_stage_t *stage, int index, kon_prop_t prop, float to, fl
kon_tweenTo(&stage->sprites[index].prop[prop], to, seconds, ease);
}
+void kon_stageScale(kon_stage_t *stage, int index, float scaleX, float scaleY, float seconds, kon_ease_t ease)
+{
+ kon_stageTween(stage, index, KON_PROP_SCALE_X, scaleX, seconds, ease);
+ kon_stageTween(stage, index, KON_PROP_SCALE_Y, scaleY, seconds, ease);
+}
+
+void kon_stageRotate(kon_stage_t *stage, int index, float radians, float seconds, kon_ease_t ease)
+{
+ kon_stageTween(stage, index, KON_PROP_ROTATION, radians, seconds, ease);
+}
+
void kon_stageMove(kon_stage_t *stage, int index, float x, float y, float seconds, kon_ease_t ease)
{
kon_stageTween(stage, index, KON_PROP_X, x, seconds, ease);
@@ -270,7 +286,7 @@ static void drawBackground(const kon_stage_t *stage, kon_framebuffer_t *fb, cons
x = floorf(x);
y = floorf(y);
}
- tint = tintOf(kon_tweenValue(&back->alpha), 1.0f);
+ tint = tintOf(kon_tweenValue(&back->alpha), 1.0f, 0xFFFFFFFFu);
kon_drawImageTint(fb, back->image, src, x, y, 0.0f, 0.0f, sx, sy, 0.0f, stage->filter, tint);
}
@@ -299,15 +315,15 @@ void kon_stageDraw(const kon_stage_t *stage, kon_framebuffer_t *fb, kon_layer_t
{
const kon_stageSprite_t *s = &stage->sprites[pick];
- float scale = kon_tweenValue(&s->prop[KON_PROP_SCALE]);
- float sx = s->flip ? -scale : scale;
+ float scaleX = kon_tweenValue(&s->prop[KON_PROP_SCALE_X]), scaleY = kon_tweenValue(&s->prop[KON_PROP_SCALE_Y]);
+ float sx = s->flip ? -scaleX : scaleX;
float ox = s->anchorX * (float)s->src.w, oy = s->anchorY * (float)s->src.h;
if (s->flip) ox = (float)s->src.w - ox;
- if (s->image && scale > 0.0f) {
- kon_drawImageTint(fb, s->image, s->src, kon_tweenValue(&s->prop[KON_PROP_X]), kon_tweenValue(&s->prop[KON_PROP_Y]),
- ox, oy, sx, scale, 0.0f, stage->filter,
- tintOf(kon_tweenValue(&s->prop[KON_PROP_ALPHA]), kon_tweenValue(&s->prop[KON_PROP_BRIGHTNESS])));
+ if (s->image) {
+ kon_drawImageBlend(fb, s->image, s->src, kon_tweenValue(&s->prop[KON_PROP_X]), kon_tweenValue(&s->prop[KON_PROP_Y]),
+ ox, oy, sx, scaleY, kon_tweenValue(&s->prop[KON_PROP_ROTATION]), stage->filter,
+ tintOf(kon_tweenValue(&s->prop[KON_PROP_ALPHA]), kon_tweenValue(&s->prop[KON_PROP_BRIGHTNESS]), s->color), s->blend);
}
lastZ = s->z;
lastIndex = pick;
diff --git a/kon/konstage.h b/kon/konstage.h
index 6c3b909..f19c5f0 100644
--- a/kon/konstage.h
+++ b/kon/konstage.h
@@ -62,7 +62,9 @@ typedef enum kon_prop {
KON_PROP_X,
KON_PROP_Y,
KON_PROP_ALPHA, /* 0 to 1 */
- KON_PROP_SCALE,
+ KON_PROP_SCALE_X,
+ KON_PROP_SCALE_Y,
+ KON_PROP_ROTATION, /* radians, positive turns clockwise on screen, around the anchor */
KON_PROP_BRIGHTNESS, /* 1 as drawn, lower darkens it, the usual way to show who is not talking */
KON_PROP_COUNT
} kon_prop_t;
@@ -76,6 +78,8 @@ typedef struct kon_stageSprite {
int flip;
kon_layer_t layer;
int z; /* higher is in front inside its layer, sprites with the same z go in the order they were added */
+ kon_blend_t blend; /* add and screen for glows and light, multiply for shadows and colouring */
+ uint32_t color; /* multiplies the picture's colours, 0xFFFFFFFF as drawn. only the colour is used, the alpha comes from KON_PROP_ALPHA */
int hiding; /* removes itself when it has faded out */
} kon_stageSprite_t;
@@ -108,7 +112,7 @@ void kon_stageBackground(kon_stage_t *stage, const kon_image *image, kon_fit_t f
a new background starts at zoom 1, focus 0.5 */
void kon_stageBackgroundView(kon_stage_t *stage, float zoom, float focusX, float focusY, float seconds, kon_ease_t ease);
-/* a new sprite at 0, 0 in view, not faded in. returns its index or -1 when there is no room. src NULL is the whole image.
+/* a new sprite at 0, 0 in view, not faded in. any picture can be a sprite: a face, a CG, a light beam in add blend, a vignette over the screen. returns its index or -1 when there is no room. src NULL is the whole image.
it stands on the bottom middle of itself, change anchorX and anchorY on the sprite for anything else */
int kon_stageAdd(kon_stage_t *stage, const kon_image *image, const kon_rect_t *src, kon_layer_t layer);
void kon_stageRemove(kon_stage_t *stage, int index);
@@ -121,6 +125,10 @@ void kon_stageFrame(kon_stage_t *stage, int index, const kon_image *image, const
void kon_stageTween(kon_stage_t *stage, int index, kon_prop_t prop, float to, float seconds, kon_ease_t ease);
+/* a size as a multiple of the picture's own, 1 is as drawn. a negative one flips */
+void kon_stageScale(kon_stage_t *stage, int index, float scaleX, float scaleY, float seconds, kon_ease_t ease);
+void kon_stageRotate(kon_stage_t *stage, int index, float radians, float seconds, kon_ease_t ease);
+
/* shorthands for a move, a fade and for walking to a slot along the bottom of the view */
void kon_stageMove(kon_stage_t *stage, int index, float x, float y, float seconds, kon_ease_t ease);
void kon_stageFade(kon_stage_t *stage, int index, float alpha, float seconds, kon_ease_t ease);