Mirai's Miscellaneous Misadventures
M45 / core / dialogues.c
1
2
3
4#include <mimimi.h>
5
6static void mimimi_box(struct mimimi_image *image, unsigned char stroke, unsigned char fill)
7{
8 static unsigned char colors[10][10] =
9 {
10 {0,0,0,0,0,0,0,0,0,1},
11 {0,0,0,0,0,0,0,1,1,1},
12 {0,0,0,0,0,1,1,1,1,1},
13 {0,0,0,0,1,1,1,1,2,2},
14 {0,0,0,1,1,1,2,2,2,2},
15 {0,0,1,1,1,2,2,2,2,2},
16 {0,0,1,1,2,2,2,2,2,2},
17 {0,1,1,1,2,2,2,2,2,2},
18 {0,1,1,2,2,2,2,2,2,2},
19 {1,1,1,2,2,2,2,2,2,2},
20 };
21
22 int width, height;
23 int x0, y0, x1, y1;
24 unsigned char table[3];
25 unsigned char color;
26
27 width = image->width;
28 height = image->height;
29
30 table[0] = 0;
31 table[1] = stroke;
32 table[2] = fill;
33
34 for (y1 = 0 ; y1 < height ; y1++)
35 for (x1 = 0 ; x1 < width ; x1++)
36 image->colors[x1 + y1 * width] = fill;
37
38 for (x1 = 0 ; x1 < width ; x1++)
39 {
40 image->colors[x1 + 0 * width] = stroke;
41 image->colors[x1 + 1 * width] = stroke;
42 image->colors[x1 + (height - 1) * width] = stroke;
43 image->colors[x1 + (height - 2) * width] = stroke;
44 }
45
46 for (y1 = 0 ; y1 < height ; y1++)
47 {
48 image->colors[0 + y1 * width] = stroke;
49 image->colors[1 + y1 * width] = stroke;
50 image->colors[(width - 1) + y1 * width] = stroke;
51 image->colors[(width - 2) + y1 * width] = stroke;
52 }
53
54 for (y0 = 0 ; y0 < 10 ; y0++)
55 for (x0 = 0 ; x0 < 10 ; x0++)
56 {
57 x1 = width - 1 - x0;
58 y1 = height - 1 - y0;
59
60 color = table[colors[y0][x0]];
61
62 image->colors[x0 + y0 * width] = color;
63 image->colors[x1 + y0 * width] = color;
64 image->colors[x0 + y1 * width] = color;
65 image->colors[x1 + y1 * width] = color;
66 }
67}
68
69static void mimimi_portrait(struct mimimi_image *image, struct mimimi_model *model, unsigned char background)
70{
71 static unsigned char mask[6][6] =
72 {
73 {0,0,0,0,0,0},
74 {0,0,0,0,1,1},
75 {0,0,0,1,1,1},
76 {0,0,1,1,1,1},
77 {0,1,1,1,1,1},
78 {0,1,1,1,1,1},
79 };
80
81 int width, height;
82 struct mimimi_pose pose;
83 int i;
84 int x0, y0, x1, y1;
85
86 width = image->width;
87 height = image->height;
88
89 pose.layers[0].slant = 0;
90 pose.layers[0].y_angle = 42;
91 pose.layers[0].z_angle = 0;
92
93 pose.x = width / 2;
94 pose.y = height / 2 + 16;
95 pose.count = 1;
96
97 mimimi_pose(image, model, &pose);
98
99 for (i = 0 ; i < width * height ; i++)
100 {
101 if (image->colors[i] == 0)
102 image->colors[i] = background;
103 }
104
105 for (y0 = 0 ; y0 < 6 ; y0++)
106 for (x0 = 0 ; x0 < 6 ; x0++)
107 {
108 if (mask[y0][x0] != 0) continue;
109
110 x1 = width - 1 - x0;
111 y1 = height - 1 - y0;
112
113 image->colors[x0 + y0 * width] = 0;
114 image->colors[x1 + y0 * width] = 0;
115 image->colors[x0 + y1 * width] = 0;
116 image->colors[x1 + y1 * width] = 0;
117 }
118}
119
120static void mimimi_stamp(struct mimimi_image *target, int x0, int y0, struct mimimi_image *source)
121{
122 int x1, y1;
123 int x, y;
124 unsigned char color;
125
126 for (y1 = 0 ; y1 < source->height ; y1++)
127 for (x1 = 0 ; x1 < source->width ; x1++)
128 {
129 x = x0 + x1;
130 y = y0 + y1;
131
132 if (x < 0) continue;
133 if (y < 0) continue;
134
135 if (x >= target->width) break;
136 if (y >= target->height) return;
137
138 color = source->colors[x1 + y1 * source->width];
139 if (color == 0) continue;
140
141 target->colors[x + y * target->width] = color;
142 }
143}
144
145static void mimimi_dialogue_box(struct mimimi_image *box, struct mimimi_model *model, char *name, int width, char *paragraph)
146{
147 char *text;
148 int count;
149 int height;
150 unsigned char colors[18 * 18];
151 struct mimimi_image portrait;
152 int n, i;
153
154 text = paragraph;
155 count = 0;
156 while (*text != 0)
157 {
158 text = mimimi_skip_line(mimimi_font, text, width - 12);
159 count++;
160 }
161
162 height = 30 + 14 * count;
163
164 box->width = width;
165 box->height = height;
166 mimimi_box(box, 4, 13);
167
168 portrait.width = 18;
169 portrait.height = 18;
170 portrait.colors = colors;
171 mimimi_portrait(&portrait, model, 8);
172 mimimi_stamp(box, 6, 6, &portrait);
173
174 n = mimimi_draw_paragraph(mimimi_font, name, box, 28, 7, 4);
175 for (i = 28 ; i < n - 1 ; i++)
176 box->colors[i + 18 * box->width] = 4;
177
178 mimimi_draw_text(mimimi_font, paragraph, width - 12, 14, box, 6, 24, 4);
179}
180
181void mimimi_strip_dialogue(struct mimimi_strip_dialogue *strip_dialogue, struct mimimi_dialogue *dialogue, struct mimimi_engine *engine)
182{
183 static int width = 128;
184 static int height = 2048;
185
186 int i;
187 struct mimimi_dialogue_paragraph *paragraph;
188 void *texture;
189 struct mimimi_image image;
190 unsigned char colors[128 * 512];
191 int notch;
192
193 notch = 0;
194
195 strip_dialogue->image.width = width;
196 strip_dialogue->image.height = height;
197 strip_dialogue->image.colors = strip_dialogue->colors;
198 for (i = 0 ; i < width * height ; i++)
199 strip_dialogue->image.colors[i] = 0;
200
201 for (i = 0 ; i < dialogue->count ; i++)
202 {
203 image.colors = colors;
204 paragraph = dialogue->paragraphs + i;
205 mimimi_dialogue_box(&image, paragraph->model, paragraph->name, width, paragraph->text);
206 mimimi_stamp(&strip_dialogue->image, 0, notch, &image);
207 notch += image.height + 8;
208 strip_dialogue->notches[i] = notch;
209 }
210
211 texture = (*engine->texture)(engine->data, &strip_dialogue->image);
212
213 strip_dialogue->engine = engine;
214 strip_dialogue->count = dialogue->count;
215 strip_dialogue->texture = texture;
216 strip_dialogue->held = 1;
217 strip_dialogue->i = 0;
218 strip_dialogue->x = 0;
219 strip_dialogue->y = 0;
220}
221
222unsigned char mimimi_strip_dialogue_tick(struct mimimi_strip_dialogue *dialogue, unsigned char held)
223{
224 struct mimimi_engine *engine;
225 int distance;
226
227 if (dialogue->i >= dialogue->count) return 1;
228
229 engine = dialogue->engine;
230
231 if (dialogue->i < dialogue->count)
232 {
233 (*engine->stamp)(engine->data, 8, engine->size.height - dialogue->y, dialogue->texture);
234
235 distance = dialogue->notches[dialogue->i] - dialogue->y;
236 if (distance > 0) dialogue->y += (distance - 1) / 8 + 1;
237
238 if (dialogue->held == 0 && held != 0)
239 dialogue->i++;
240 dialogue->held = held;
241 }
242 else
243 {
244 if (dialogue->x >= 32) return 1;
245 (*engine->stamp)(engine->data, 8 - (128 + 8) * dialogue->x / 32, engine->size.height - dialogue->notches[dialogue->count - 1], dialogue->texture);
246 }
247
248 return 0;
249}
250
251void mimimi_toast_dialogue(struct mimimi_toast_dialogue *toast_dialogue, struct mimimi_dialogue *dialogue, struct mimimi_engine *engine)
252{
253 struct mimimi_image images[0x80];
254 int width;
255 int i;
256 struct mimimi_dialogue_paragraph *paragraph;
257 int count;
258 unsigned char *colors;
259
260 width = 128;
261 colors = toast_dialogue->colors;
262
263 for (i = 0 ; i < dialogue->count ; i++)
264 {
265 paragraph = dialogue->paragraphs + i;
266
267 images[i].colors = colors;
268 mimimi_dialogue_box(images + i, paragraph->model, paragraph->name, width, paragraph->text);
269 colors += images[i].width + images[i].height;
270 toast_dialogue->heights[i] = images[i].height + 8;
271 toast_dialogue->textures[i] = (*engine->texture)(engine->data, images + i);
272
273 count = 0;
274 while (paragraph->text[count] != 0) count++;
275 toast_dialogue->delays[i] = count * 4;
276 }
277
278 toast_dialogue->engine = engine;
279 toast_dialogue->count = dialogue->count;
280 toast_dialogue->i = 0;
281 toast_dialogue->j = 0;
282 toast_dialogue->k = 0;
283}
284
285unsigned char mimimi_toast_dialogue_top_tick(struct mimimi_toast_dialogue *dialogue)
286{
287 int i;
288 int height;
289 struct mimimi_engine *engine;
290
291 i = dialogue->i;
292 if (i >= dialogue->count) return 1;
293
294 height = dialogue->heights[i];
295 engine = dialogue->engine;
296
297 if (dialogue->k == 0)
298 {
299 (*engine->stamp)(engine->data, (128 + 8) * dialogue->j / 16 - 128, 8, dialogue->textures[i]);
300 dialogue->j++;
301 if (dialogue->j >= 16)
302 {
303 dialogue->j = 0;
304 dialogue->k++;
305 }
306 return 0;
307 }
308
309 if (dialogue->k == 1)
310 {
311 (*engine->stamp)(engine->data, 8, 8, dialogue->textures[i]);
312 dialogue->j++;
313 if (dialogue->j >= dialogue->delays[i])
314 {
315 dialogue->j = 0;
316 dialogue->k++;
317 }
318 return 0;
319 }
320
321 if (dialogue->k == 2)
322 {
323 (*engine->stamp)(engine->data, 8, 8 - height * dialogue->j / 32, dialogue->textures[i]);
324 dialogue->j++;
325 if (dialogue->j >= 32)
326 {
327 dialogue->j = 0;
328 dialogue->k = 0;
329 dialogue->i++;
330 }
331 return 0;
332 }
333
334
335 return 1;
336}
337
338unsigned char mimimi_toast_dialogue_bottom_tick(struct mimimi_toast_dialogue *dialogue)
339{
340 int i;
341 int height;
342 struct mimimi_engine *engine;
343
344 i = dialogue->i;
345 if (i >= dialogue->count) return 1;
346
347 height = dialogue->heights[i];
348 engine = dialogue->engine;
349
350 if (dialogue->k == 0)
351 {
352 (*engine->stamp)(engine->data, 8, engine->size.height - dialogue->j * height / 16, dialogue->textures[i]);
353 dialogue->j++;
354 if (dialogue->j >= 16)
355 {
356 dialogue->j = 0;
357 dialogue->k++;
358 }
359 return 0;
360 }
361
362 if (dialogue->k == 1)
363 {
364 (*engine->stamp)(engine->data, 8, engine->size.height - height, dialogue->textures[i]);
365 dialogue->j++;
366 if (dialogue->j >= dialogue->delays[i])
367 {
368 dialogue->j = 0;
369 dialogue->k++;
370 }
371 return 0;
372 }
373
374 if (dialogue->k == 2)
375 {
376 (*engine->stamp)(engine->data, 8 - (128 + 8) * dialogue->j / 32, engine->size.height - height, dialogue->textures[i]);
377 dialogue->j++;
378 if (dialogue->j >= 32)
379 {
380 dialogue->j = 0;
381 dialogue->k = 0;
382 dialogue->i++;
383 }
384 return 0;
385 }
386
387
388 return 1;
389}