1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
|
/* SPDX-License-Identifier: MIT */
/*
* konstage.h
*
* Copyright (c) 2026 KonAki
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
#ifndef KONSTAGE_H
#define KONSTAGE_H
#include "konsofren.h"
#include "kon2d.h"
/*** definition ***/
/* the picture behind everything. none leaves the framebuffer as it is, so a map or a scene drawn first shows through */
typedef enum kon_fit {
KON_FIT_NONE,
KON_FIT_STRETCH, /* fills the view, squashing the picture if the shapes differ */
KON_FIT_COVER, /* fills the view keeping the shape, the edges that don't fit are cut off */
KON_FIT_CONTAIN, /* the whole picture keeping the shape, the rest of the view is left alone */
KON_FIT_CENTER /* the picture as it is, in the middle */
} kon_fit_t;
/* sprites are drawn in two goes so the game can put its text box in between. back is under the box, front is over it,
so a see through effect on a sprite does not turn into a smear over the text */
typedef enum kon_layer {
KON_LAYER_BACK,
KON_LAYER_FRONT
} kon_layer_t;
/* standing places across the view, where a sprite goes with kon_stagePlace. their x is stage->slotX, as a share of the width */
typedef enum kon_slot {
KON_SLOT_FAR_LEFT,
KON_SLOT_LEFT,
KON_SLOT_CENTER,
KON_SLOT_RIGHT,
KON_SLOT_FAR_RIGHT,
KON_SLOT_COUNT
} kon_slot_t;
/* what kon_stageTween can glide */
typedef enum kon_prop {
KON_PROP_X,
KON_PROP_Y,
KON_PROP_ALPHA, /* 0 to 1 */
KON_PROP_SCALE,
KON_PROP_BRIGHTNESS, /* 1 as drawn, lower darkens it, the usual way to show who is not talking */
KON_PROP_COUNT
} kon_prop_t;
typedef struct kon_stageSprite {
int used;
const kon_image *image;
kon_rect_t src; /* w == 0 is the whole image */
kon_tween_t prop[KON_PROP_COUNT];
float anchorX, anchorY; /* the point of the sprite, 0 to 1, that sits at x, y. 0.5, 1 is the middle of its feet */
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 */
int hiding; /* removes itself when it has faded out */
} kon_stageSprite_t;
typedef struct kon_stageBackground {
const kon_image *image;
kon_fit_t fit;
kon_tween_t alpha;
kon_tween_t zoom, focusX, focusY;
} kon_stageBackground_t;
/* the stage does not own its sprites or the images, sprites is room for capacity of them */
typedef struct kon_stage {
int width, height; /* the view, in the pixels you draw at */
kon_stageSprite_t *sprites;
int capacity;
float slotX[KON_SLOT_COUNT];
kon_filter_t filter; /* for sprites and the background that get scaled */
kon_stageBackground_t back, old;
} kon_stage_t;
/*** functions ***/
void kon_stageInit(kon_stage_t *stage, kon_stageSprite_t *sprites, int capacity, int width, int height);
/* the background fades in over the old one for seconds, 0 swaps at once. image NULL clears it */
void kon_stageBackground(kon_stage_t *stage, const kon_image *image, kon_fit_t fit, float seconds);
/* pans and zooms the background, which is what a CG wants. zoom 1 shows it as the fit says and 2 shows half of it. focus is the point of
the picture, 0 to 1 across and down, kept in the middle of the view. a picture that fills the view never lets its edge slide in.
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.
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);
/* moves a sprite to the other side of the text box. they start in the back layer, behind the box, which is where characters belong */
void kon_stageLayer(kon_stage_t *stage, int index, kon_layer_t layer);
/* swaps the picture, for a new expression. the sprite keeps where it is */
void kon_stageFrame(kon_stage_t *stage, int index, const kon_image *image, const kon_rect_t *src);
void kon_stageTween(kon_stage_t *stage, int index, kon_prop_t prop, float to, 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);
void kon_stagePlace(kon_stage_t *stage, int index, kon_slot_t slot, float seconds, kon_ease_t ease);
/* fades out and removes itself */
void kon_stageHide(kon_stage_t *stage, int index, float seconds);
void kon_stageUpdate(kon_stage_t *stage, float dt);
/* 1 while anything is still gliding or fading, for a script that waits for it */
int kon_stageBusy(const kon_stage_t *stage);
/* draw the background and then the back layer, then your text box, then the front layer. without a background pass 0 */
void kon_stageDrawBackground(const kon_stage_t *stage, kon_framebuffer_t *fb);
void kon_stageDraw(const kon_stage_t *stage, kon_framebuffer_t *fb, kon_layer_t layer);
#endif
|