Mirai's Miscellaneous Misadventures
M47 / core / dialogues.c
#include <mimimi.h>
static void mimimi_box(struct mimimi_image *image, unsigned char stroke, unsigned char fill)
{
static unsigned char colors[10][10] =
{
{0,0,0,0,0,0,0,0,0,1},
{0,0,0,0,0,0,0,1,1,1},
{0,0,0,0,0,1,1,1,1,1},
{0,0,0,0,1,1,1,1,2,2},
{0,0,0,1,1,1,2,2,2,2},
{0,0,1,1,1,2,2,2,2,2},
{0,0,1,1,2,2,2,2,2,2},
{0,1,1,1,2,2,2,2,2,2},
{0,1,1,2,2,2,2,2,2,2},
{1,1,1,2,2,2,2,2,2,2},
};
int width, height;
int x0, y0, x1, y1;
unsigned char table[3];
unsigned char color;
width = image->width;
height = image->height;
table[0] = 0;
table[1] = stroke;
table[2] = fill;
for (y1 = 0 ; y1 < height ; y1++)
for (x1 = 0 ; x1 < width ; x1++)
image->colors[x1 + y1 * width] = fill;
for (x1 = 0 ; x1 < width ; x1++)
{
image->colors[x1 + 0 * width] = stroke;
image->colors[x1 + 1 * width] = stroke;
image->colors[x1 + (height - 1) * width] = stroke;
image->colors[x1 + (height - 2) * width] = stroke;
}
for (y1 = 0 ; y1 < height ; y1++)
{
image->colors[0 + y1 * width] = stroke;
image->colors[1 + y1 * width] = stroke;
image->colors[(width - 1) + y1 * width] = stroke;
image->colors[(width - 2) + y1 * width] = stroke;
}
for (y0 = 0 ; y0 < 10 ; y0++)
for (x0 = 0 ; x0 < 10 ; x0++)
{
x1 = width - 1 - x0;
y1 = height - 1 - y0;
color = table[colors[y0][x0]];
image->colors[x0 + y0 * width] = color;
image->colors[x1 + y0 * width] = color;
image->colors[x0 + y1 * width] = color;
image->colors[x1 + y1 * width] = color;
}
}
static void mimimi_portrait(struct mimimi_image *image, struct mimimi_model *model, unsigned char background)
{
static unsigned char mask[6][6] =
{
{0,0,0,0,0,0},
{0,0,0,0,1,1},
{0,0,0,1,1,1},
{0,0,1,1,1,1},
{0,1,1,1,1,1},
{0,1,1,1,1,1},
};
int width, height;
struct mimimi_pose pose;
int i;
int x0, y0, x1, y1;
width = image->width;
height = image->height;
pose.layers[0].slant = 0;
pose.layers[0].y_angle = 42;
pose.layers[0].z_angle = 0;
pose.x = width / 2;
pose.y = height / 2 + 16;
pose.count = 1;
mimimi_pose(image, model, &pose);
for (i = 0 ; i < width * height ; i++)
{
if (image->colors[i] == 0)
image->colors[i] = background;
}
for (y0 = 0 ; y0 < 6 ; y0++)
for (x0 = 0 ; x0 < 6 ; x0++)
{
if (mask[y0][x0] != 0) continue;
x1 = width - 1 - x0;
y1 = height - 1 - y0;
image->colors[x0 + y0 * width] = 0;
image->colors[x1 + y0 * width] = 0;
image->colors[x0 + y1 * width] = 0;
image->colors[x1 + y1 * width] = 0;
}
}
static void mimimi_stamp(struct mimimi_image *target, int x0, int y0, struct mimimi_image *source)
{
int x1, y1;
int x, y;
unsigned char color;
for (y1 = 0 ; y1 < source->height ; y1++)
for (x1 = 0 ; x1 < source->width ; x1++)
{
x = x0 + x1;
y = y0 + y1;
if (x < 0) continue;
if (y < 0) continue;
if (x >= target->width) break;
if (y >= target->height) return;
color = source->colors[x1 + y1 * source->width];
if (color == 0) continue;
target->colors[x + y * target->width] = color;
}
}
static void mimimi_dialogue_box(struct mimimi_image *box, struct mimimi_model *model, char *name, int width, char *paragraph)
{
char *text;
int count;
int height;
unsigned char colors[18 * 18];
struct mimimi_image portrait;
int n, i;
text = paragraph;
count = 0;
while (*text != 0)
{
text = mimimi_skip_line(mimimi_font, text, width - 12);
count++;
}
height = 30 + 14 * count;
box->width = width;
box->height = height;
mimimi_box(box, 4, 13);
portrait.width = 18;
portrait.height = 18;
portrait.colors = colors;
mimimi_portrait(&portrait, model, 8);
mimimi_stamp(box, 6, 6, &portrait);
n = mimimi_draw_paragraph(mimimi_font, name, box, 28, 7, 4);
for (i = 28 ; i < n - 1 ; i++)
box->colors[i + 18 * box->width] = 4;
mimimi_draw_text(mimimi_font, paragraph, width - 12, 14, box, 6, 24, 4);
}
void mimimi_strip_dialogue(struct mimimi_strip_dialogue *strip_dialogue, struct mimimi_dialogue *dialogue, struct mimimi_engine *engine)
{
static int width = 128;
static int height = 2048;
int i;
struct mimimi_dialogue_paragraph *paragraph;
void *texture;
struct mimimi_image image;
unsigned char colors[128 * 512];
int notch;
notch = 0;
strip_dialogue->image.width = width;
strip_dialogue->image.height = height;
strip_dialogue->image.colors = strip_dialogue->colors;
for (i = 0 ; i < width * height ; i++)
strip_dialogue->image.colors[i] = 0;
for (i = 0 ; i < dialogue->count ; i++)
{
image.colors = colors;
paragraph = dialogue->paragraphs + i;
mimimi_dialogue_box(&image, paragraph->model, paragraph->name, width, paragraph->text);
mimimi_stamp(&strip_dialogue->image, 0, notch, &image);
notch += image.height + 8;
strip_dialogue->notches[i] = notch;
}
texture = (*engine->texture)(engine->data, &strip_dialogue->image);
strip_dialogue->engine = engine;
strip_dialogue->count = dialogue->count;
strip_dialogue->texture = texture;
strip_dialogue->held = 1;
strip_dialogue->i = 0;
strip_dialogue->x = 0;
strip_dialogue->y = 0;
}
unsigned char mimimi_strip_dialogue_tick(struct mimimi_strip_dialogue *dialogue, unsigned char held)
{
struct mimimi_engine *engine;
int distance;
if (dialogue->i >= dialogue->count) return 1;
engine = dialogue->engine;
if (dialogue->i < dialogue->count)
{
(*engine->stamp)(engine->data, 8, engine->size.height - dialogue->y, dialogue->texture);
distance = dialogue->notches[dialogue->i] - dialogue->y;
if (distance > 0) dialogue->y += (distance - 1) / 8 + 1;
if (dialogue->held == 0 && held != 0)
dialogue->i++;
dialogue->held = held;
}
else
{
if (dialogue->x >= 32) return 1;
(*engine->stamp)(engine->data, 8 - (128 + 8) * dialogue->x / 32, engine->size.height - dialogue->notches[dialogue->count - 1], dialogue->texture);
}
return 0;
}
void mimimi_toast_dialogue(struct mimimi_toast_dialogue *toast_dialogue, struct mimimi_dialogue *dialogue, struct mimimi_engine *engine)
{
struct mimimi_image images[0x80];
int width;
int i;
struct mimimi_dialogue_paragraph *paragraph;
int count;
unsigned char *colors;
width = 128;
colors = toast_dialogue->colors;
for (i = 0 ; i < dialogue->count ; i++)
{
paragraph = dialogue->paragraphs + i;
images[i].colors = colors;
mimimi_dialogue_box(images + i, paragraph->model, paragraph->name, width, paragraph->text);
colors += images[i].width + images[i].height;
toast_dialogue->heights[i] = images[i].height + 8;
toast_dialogue->textures[i] = (*engine->texture)(engine->data, images + i);
count = 0;
while (paragraph->text[count] != 0) count++;
toast_dialogue->delays[i] = count * 4;
}
toast_dialogue->engine = engine;
toast_dialogue->count = dialogue->count;
toast_dialogue->i = 0;
toast_dialogue->j = 0;
toast_dialogue->k = 0;
}
unsigned char mimimi_toast_dialogue_top_tick(struct mimimi_toast_dialogue *dialogue)
{
int i;
int height;
struct mimimi_engine *engine;
i = dialogue->i;
if (i >= dialogue->count) return 1;
height = dialogue->heights[i];
engine = dialogue->engine;
if (dialogue->k == 0)
{
(*engine->stamp)(engine->data, (128 + 8) * dialogue->j / 16 - 128, 8, dialogue->textures[i]);
dialogue->j++;
if (dialogue->j >= 16)
{
dialogue->j = 0;
dialogue->k++;
}
return 0;
}
if (dialogue->k == 1)
{
(*engine->stamp)(engine->data, 8, 8, dialogue->textures[i]);
dialogue->j++;
if (dialogue->j >= dialogue->delays[i])
{
dialogue->j = 0;
dialogue->k++;
}
return 0;
}
if (dialogue->k == 2)
{
(*engine->stamp)(engine->data, 8, 8 - height * dialogue->j / 32, dialogue->textures[i]);
dialogue->j++;
if (dialogue->j >= 32)
{
dialogue->j = 0;
dialogue->k = 0;
dialogue->i++;
}
return 0;
}
return 1;
}
unsigned char mimimi_toast_dialogue_bottom_tick(struct mimimi_toast_dialogue *dialogue)
{
int i;
int height;
struct mimimi_engine *engine;
i = dialogue->i;
if (i >= dialogue->count) return 1;
height = dialogue->heights[i];
engine = dialogue->engine;
if (dialogue->k == 0)
{
(*engine->stamp)(engine->data, 8, engine->size.height - dialogue->j * height / 16, dialogue->textures[i]);
dialogue->j++;
if (dialogue->j >= 16)
{
dialogue->j = 0;
dialogue->k++;
}
return 0;
}
if (dialogue->k == 1)
{
(*engine->stamp)(engine->data, 8, engine->size.height - height, dialogue->textures[i]);
dialogue->j++;
if (dialogue->j >= dialogue->delays[i])
{
dialogue->j = 0;
dialogue->k++;
}
return 0;
}
if (dialogue->k == 2)
{
(*engine->stamp)(engine->data, 8 - (128 + 8) * dialogue->j / 32, engine->size.height - height, dialogue->textures[i]);
dialogue->j++;
if (dialogue->j >= 32)
{
dialogue->j = 0;
dialogue->k = 0;
dialogue->i++;
}
return 0;
}
return 1;
}