audio: implement stop/fadeout
This commit is contained in:
parent
f22989d544
commit
22aa0dd60e
@ -76,6 +76,7 @@ label start:
|
|||||||
#voice "n4test.mp3"
|
#voice "n4test.mp3"
|
||||||
play TinyForestMinstrels "music/TinyForestMinstrels.ogg"
|
play TinyForestMinstrels "music/TinyForestMinstrels.ogg"
|
||||||
n "Tiny minstrels can be heard amongst the trees"
|
n "Tiny minstrels can be heard amongst the trees"
|
||||||
|
stop TinyForestMinstrels fadeout 5.5
|
||||||
|
|
||||||
|
|
||||||
scene bgforest1
|
scene bgforest1
|
||||||
|
|||||||
@ -6,4 +6,6 @@ namespace audio {
|
|||||||
void init();
|
void init();
|
||||||
void load(renpy::language::audio const * const audio, int count);
|
void load(renpy::language::audio const * const audio, int count);
|
||||||
void update();
|
void update();
|
||||||
|
void play(int audio_index);
|
||||||
|
void stop(int audio_index, double fadeout);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -25,8 +25,7 @@ namespace renpy::language {
|
|||||||
|
|
||||||
struct audio {
|
struct audio {
|
||||||
char const * const path;
|
char const * const path;
|
||||||
char const * const name;
|
double loop_end;
|
||||||
uint32_t loop;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
struct image {
|
struct image {
|
||||||
@ -66,6 +65,11 @@ namespace renpy::language {
|
|||||||
uint32_t audioIndex;
|
uint32_t audioIndex;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct stop {
|
||||||
|
uint32_t audioIndex;
|
||||||
|
double fadeout;
|
||||||
|
};
|
||||||
|
|
||||||
struct _return {
|
struct _return {
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -94,10 +98,6 @@ namespace renpy::language {
|
|||||||
struct with {
|
struct with {
|
||||||
};
|
};
|
||||||
|
|
||||||
struct stop {
|
|
||||||
uint32_t channelIndex;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct pause {
|
struct pause {
|
||||||
float duration;
|
float duration;
|
||||||
};
|
};
|
||||||
|
|||||||
@ -478,18 +478,19 @@ def parse_stop(tokens, index):
|
|||||||
if channel.type != TT.IDENTIFIER:
|
if channel.type != TT.IDENTIFIER:
|
||||||
raise ParseException("expected identifier", channel)
|
raise ParseException("expected identifier", channel)
|
||||||
|
|
||||||
index += 1
|
|
||||||
token = tokens[index]
|
|
||||||
fadeout = None
|
|
||||||
if token.type == TT.FADEOUT:
|
|
||||||
fadeout = tokens[index + 1]
|
fadeout = tokens[index + 1]
|
||||||
if fadeout.type != TT.NUMBER:
|
if fadeout.type != TT.FADEOUT:
|
||||||
raise ParseException("expected number", fadeout)
|
raise ParseException("expected fadeout", channel)
|
||||||
index += 2
|
|
||||||
|
number = tokens[index + 2]
|
||||||
|
if number.type != TT.NUMBER:
|
||||||
|
raise ParseException("expected number", number)
|
||||||
|
|
||||||
|
index += 3
|
||||||
|
|
||||||
stop = Stop(
|
stop = Stop(
|
||||||
channel = channel,
|
channel = channel,
|
||||||
fadeout = fadeout
|
fadeout = number
|
||||||
)
|
)
|
||||||
return index, stop
|
return index, stop
|
||||||
|
|
||||||
|
|||||||
@ -20,6 +20,7 @@ class State:
|
|||||||
characters_lookup: dict[str, int] # identifier to character index
|
characters_lookup: dict[str, int] # identifier to character index
|
||||||
labels_lookup: dict[str, int] # identifier to statement index
|
labels_lookup: dict[str, int] # identifier to statement index
|
||||||
audio_lookup: dict[str, int]
|
audio_lookup: dict[str, int]
|
||||||
|
channel_lookup: dict[str, int]
|
||||||
string_lookup: dict[str, int]
|
string_lookup: dict[str, int]
|
||||||
|
|
||||||
global_identifiers: set[str]
|
global_identifiers: set[str]
|
||||||
@ -83,11 +84,15 @@ def pass1(state, ast):
|
|||||||
key = lhs_key(ast.name)
|
key = lhs_key(ast.name)
|
||||||
assert key not in state.labels_lookup
|
assert key not in state.labels_lookup
|
||||||
state.labels_lookup[key] = len(state.statements)
|
state.labels_lookup[key] = len(state.statements)
|
||||||
elif type(ast) in {parse.Play, parse.Voice}:
|
elif type(ast) is parse.Play:
|
||||||
if ast.path.lexeme not in state.audio_lookup:
|
if ast.path.lexeme not in state.audio_lookup:
|
||||||
index = len(state.audio_lookup)
|
index = len(state.audio_lookup)
|
||||||
channel = ast.channel.lexeme if type(ast) is parse.Play else None
|
state.audio_lookup[ast.path.lexeme] = index
|
||||||
state.audio_lookup[ast.path.lexeme] = (index, channel)
|
state.channel_lookup[ast.channel.lexeme] = index
|
||||||
|
elif type(ast) is parse.Voice:
|
||||||
|
if ast.path.lexeme not in state.audio_lookup:
|
||||||
|
index = len(state.audio_lookup)
|
||||||
|
state.audio_lookup[ast.path.lexeme] = index
|
||||||
elif type(ast) is parse.Say:
|
elif type(ast) is parse.Say:
|
||||||
if ast.text.lexeme not in state.string_lookup:
|
if ast.text.lexeme not in state.string_lookup:
|
||||||
index = len(state.string_lookup)
|
index = len(state.string_lookup)
|
||||||
@ -143,8 +148,7 @@ def parse_color(b):
|
|||||||
def pass2_statement(state, pc, statement):
|
def pass2_statement(state, pc, statement):
|
||||||
if type(statement) is parse.Play:
|
if type(statement) is parse.Play:
|
||||||
comment = statement.path.lexeme.decode('utf-8')
|
comment = statement.path.lexeme.decode('utf-8')
|
||||||
audio_index, channel = state.audio_lookup[statement.path.lexeme]
|
audio_index = state.audio_lookup[statement.path.lexeme]
|
||||||
assert channel is not None
|
|
||||||
yield f"{{ .type = type::play, .play = {{ .audioIndex = {audio_index} }} }}, // {pc} {comment}"
|
yield f"{{ .type = type::play, .play = {{ .audioIndex = {audio_index} }} }}, // {pc} {comment}"
|
||||||
elif type(statement) is parse.Scene:
|
elif type(statement) is parse.Scene:
|
||||||
key = lhs_key(statement.name)
|
key = lhs_key(statement.name)
|
||||||
@ -166,8 +170,7 @@ def pass2_statement(state, pc, statement):
|
|||||||
assert False, (pc, statement)
|
assert False, (pc, statement)
|
||||||
elif type(statement) is parse.Voice:
|
elif type(statement) is parse.Voice:
|
||||||
comment = statement.path.lexeme.decode('utf-8')
|
comment = statement.path.lexeme.decode('utf-8')
|
||||||
audio_index, channel = state.audio_lookup[statement.path.lexeme]
|
audio_index = state.audio_lookup[statement.path.lexeme]
|
||||||
assert channel is None
|
|
||||||
yield f"{{ .type = type::voice, .voice = {{ .audioIndex = {audio_index} }} }}, // {pc} {comment}"
|
yield f"{{ .type = type::voice, .voice = {{ .audioIndex = {audio_index} }} }}, // {pc} {comment}"
|
||||||
elif type(statement) is parse.Say:
|
elif type(statement) is parse.Say:
|
||||||
key = lhs_key(statement.speaker)
|
key = lhs_key(statement.speaker)
|
||||||
@ -201,7 +204,10 @@ def pass2_statement(state, pc, statement):
|
|||||||
elif type(statement) is parse.Return:
|
elif type(statement) is parse.Return:
|
||||||
yield f"{{ .type = type::_return }}, // {pc}"
|
yield f"{{ .type = type::_return }}, // {pc}"
|
||||||
elif type(statement) is parse.Stop:
|
elif type(statement) is parse.Stop:
|
||||||
yield f"{{ .type = type::stop, .stop = {{ /* FIXME channel */ }} }}, // {pc}"
|
audio_index = state.channel_lookup[statement.channel.lexeme]
|
||||||
|
fadeout = statement.fadeout.lexeme
|
||||||
|
channel = statement.channel.lexeme.decode('utf-8')
|
||||||
|
yield f"{{ .type = type::stop, .stop = {{ .audioIndex = {audio_index}, .fadeout = {float(fadeout)} }} }}, // {pc} {channel}"
|
||||||
elif type(statement) is parse.Pause:
|
elif type(statement) is parse.Pause:
|
||||||
duration = statement.duration.lexeme
|
duration = statement.duration.lexeme
|
||||||
yield f"{{ .type = type::pause, .pause = {{ .duration = {duration} }} }}, // {pc}"
|
yield f"{{ .type = type::pause, .pause = {{ .duration = {duration} }} }}, // {pc}"
|
||||||
@ -241,7 +247,8 @@ def pass2_characters(state):
|
|||||||
|
|
||||||
def pass2_audio(state):
|
def pass2_audio(state):
|
||||||
yield "const language::audio audio[] = {"
|
yield "const language::audio audio[] = {"
|
||||||
for audio, (i, channel) in sorted(state.audio_lookup.items(), key=lambda kv: kv[1][0]):
|
reverse_channel = {v: k for k, v in state.channel_lookup.items()}
|
||||||
|
for audio, i in sorted(state.audio_lookup.items(), key=lambda kv: kv[1]):
|
||||||
orig_path = audio.decode('utf-8')
|
orig_path = audio.decode('utf-8')
|
||||||
path = orig_path
|
path = orig_path
|
||||||
if path.endswith(".mp3"):
|
if path.endswith(".mp3"):
|
||||||
@ -251,11 +258,11 @@ def pass2_audio(state):
|
|||||||
else:
|
else:
|
||||||
assert False, path
|
assert False, path
|
||||||
name = audio
|
name = audio
|
||||||
channel_name = channel.decode('utf-8') if channel is not None else None
|
channel_name = reverse_channel[i].decode('utf-8') if i in reverse_channel else None
|
||||||
name = f"\"{channel_name}\"" if channel is not None else "nullptr"
|
name = f"\"{channel_name}\"" if channel_name is not None else "nullptr"
|
||||||
loop = loops[channel_name] if channel_name in loops else 0
|
loop = loops[channel_name] if channel_name in loops else 0
|
||||||
assert loop < 20_000, loop
|
assert loop < 20_000, loop
|
||||||
yield f"{{ .path = \"audio/{path}.opus.bin\", .name = {name}, .loop = {int(loop * 48000)} }}, // {i} {orig_path}"
|
yield f"{{ .path = \"audio/{path}.opus.bin\", .loop_end = {float(loop)} }}, // {i} {orig_path}"
|
||||||
yield "};"
|
yield "};"
|
||||||
yield "const int audio_length = (sizeof (audio)) / (sizeof (audio[0]));"
|
yield "const int audio_length = (sizeof (audio)) / (sizeof (audio[0]));"
|
||||||
|
|
||||||
@ -313,6 +320,7 @@ image _internal_flowers = "flowers.png"
|
|||||||
characters_lookup = dict(),
|
characters_lookup = dict(),
|
||||||
labels_lookup = dict(),
|
labels_lookup = dict(),
|
||||||
audio_lookup = dict(),
|
audio_lookup = dict(),
|
||||||
|
channel_lookup = dict(),
|
||||||
string_lookup = dict(),
|
string_lookup = dict(),
|
||||||
global_identifiers = set(),
|
global_identifiers = set(),
|
||||||
)
|
)
|
||||||
|
|||||||
163
src/audio.cpp
163
src/audio.cpp
@ -13,20 +13,23 @@
|
|||||||
|
|
||||||
namespace audio {
|
namespace audio {
|
||||||
|
|
||||||
int const frame_samples = 960; // 20 milliseconds @ 48kHz
|
static int const frame_samples = 960; // 20 milliseconds @ 48kHz
|
||||||
int const sample_rate = 48000;
|
static int const sample_rate = 48000;
|
||||||
int const channels = 2;
|
static int const channels = 2;
|
||||||
int const sample_size = (sizeof (int16_t));
|
static int const sample_size = (sizeof (int16_t));
|
||||||
|
|
||||||
int const max_frame_size = 960 * 3; // 20ms at 48kHz
|
static int const max_frame_size = 960 * 3; // 20ms at 48kHz
|
||||||
int const max_packet_size = 1275;
|
static int const max_packet_size = 1275;
|
||||||
|
|
||||||
|
static int const half_period_samples = sample_rate / 2;
|
||||||
|
static int const half_period_size = half_period_samples * sample_size * channels;
|
||||||
|
|
||||||
//
|
//
|
||||||
|
|
||||||
SDL_AudioStream * audio_stream;
|
static SDL_AudioStream * audio_stream;
|
||||||
SDL_AudioSpec audio_spec;
|
static SDL_AudioSpec audio_spec;
|
||||||
|
|
||||||
OpusDecoder * opus_decoder;
|
static OpusDecoder * opus_decoder;
|
||||||
|
|
||||||
struct AudioBuffer {
|
struct AudioBuffer {
|
||||||
renpy::language::audio const * audio;
|
renpy::language::audio const * audio;
|
||||||
@ -35,16 +38,20 @@ namespace audio {
|
|||||||
};
|
};
|
||||||
|
|
||||||
struct AudioInstance {
|
struct AudioInstance {
|
||||||
|
int audio_index;
|
||||||
AudioBuffer * audio_buffer;
|
AudioBuffer * audio_buffer;
|
||||||
uint32_t sample_index;
|
uint32_t sample_index;
|
||||||
uint32_t tail_index;
|
uint32_t tail_index;
|
||||||
|
uint32_t fadeout_end;
|
||||||
|
uint32_t fadeout_index;
|
||||||
};
|
};
|
||||||
|
|
||||||
AudioBuffer * audio_buffers;
|
static AudioBuffer * audio_buffers;
|
||||||
|
static int audio_buffers_count;
|
||||||
|
|
||||||
constexpr int max_audio_instances = 16;
|
constexpr int max_audio_instances = 128;
|
||||||
AudioInstance audio_instances[max_audio_instances];
|
static AudioInstance audio_instances[max_audio_instances];
|
||||||
int instance_count;
|
static int audio_instances_count;
|
||||||
|
|
||||||
void init()
|
void init()
|
||||||
{
|
{
|
||||||
@ -62,7 +69,7 @@ namespace audio {
|
|||||||
assert(!"opus_decoder_create");
|
assert(!"opus_decoder_create");
|
||||||
}
|
}
|
||||||
|
|
||||||
instance_count = 0;
|
audio_instances_count = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void decode(char const * const filename, AudioBuffer * audio_buffer)
|
void decode(char const * const filename, AudioBuffer * audio_buffer)
|
||||||
@ -121,62 +128,148 @@ namespace audio {
|
|||||||
void load(renpy::language::audio const * const audio, int count)
|
void load(renpy::language::audio const * const audio, int count)
|
||||||
{
|
{
|
||||||
audio_buffers = NewM<AudioBuffer>(count);
|
audio_buffers = NewM<AudioBuffer>(count);
|
||||||
|
audio_buffers_count = count;
|
||||||
for (int i = 0; i < count; i++) {
|
for (int i = 0; i < count; i++) {
|
||||||
audio_buffers[i].audio = &audio[i];
|
audio_buffers[i].audio = &audio[i];
|
||||||
decode(audio[i].path, &audio_buffers[i]);
|
decode(audio[i].path, &audio_buffers[i]);
|
||||||
//audio_instances[i].audio_buffer = &audio_buffers[i];
|
|
||||||
//audio_instances[i].sample_index = 0;
|
|
||||||
//audio_instances[i].tail_index = audio_buffers[i].sample_count;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
inline static int min(int a, int b)
|
void play(int audio_index)
|
||||||
{
|
{
|
||||||
return (a < b) ? a : b;
|
assert(audio_index >= 0 && audio_index < audio_buffers_count);
|
||||||
|
assert(audio_instances_count < max_audio_instances);
|
||||||
|
|
||||||
|
AudioInstance & instance = audio_instances[audio_instances_count++];
|
||||||
|
|
||||||
|
instance.audio_index = (int)audio_index;
|
||||||
|
instance.audio_buffer = &audio_buffers[audio_index];
|
||||||
|
instance.sample_index = 0;
|
||||||
|
instance.tail_index = audio_buffers[audio_index].sample_count;
|
||||||
|
instance.fadeout_end = 0;
|
||||||
|
instance.fadeout_index = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void update()
|
void stop(int audio_index, double fadeout)
|
||||||
{
|
{
|
||||||
int half_period_samples = audio_spec.freq / 2;
|
assert(audio_index >= 0 && audio_index < audio_buffers_count);
|
||||||
int half_period_size = half_period_samples * sample_size * audio_spec.channels;
|
|
||||||
if (SDL_GetAudioStreamQueued(audio_stream) >= half_period_size)
|
|
||||||
return;
|
|
||||||
|
|
||||||
int16_t mix_buffer[half_period_samples * channels];
|
for (int i = 0; i < audio_instances_count; i++) {
|
||||||
memset(mix_buffer, 0, (sizeof (mix_buffer)));
|
if (audio_instances[i].audio_index == audio_index) {
|
||||||
|
if (audio_instances[i].fadeout_end == 0) {
|
||||||
|
fprintf(stderr, "audio: stop instance %d index %d\n", i, audio_index);
|
||||||
|
audio_instances[i].fadeout_end = fadeout * (double)sample_rate;
|
||||||
|
audio_instances[i].fadeout_index = 0;
|
||||||
|
} else {
|
||||||
|
fprintf(stderr, "audio: duplicate stop on instance %d index %d\n", i, audio_index);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
static inline void saturation_add(int16_t * mix_buffer, int32_t value)
|
||||||
AudioInstance & instance = audio_instances[0];
|
{
|
||||||
|
int32_t mix_value = *mix_buffer;
|
||||||
|
mix_value += value;
|
||||||
|
if (mix_value > 32767)
|
||||||
|
mix_value = 32767;
|
||||||
|
if (mix_value < -32768)
|
||||||
|
mix_value = -32768;
|
||||||
|
*mix_buffer = mix_value;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline void remove_instance(int instance_index)
|
||||||
|
{
|
||||||
|
fprintf(stderr, "removed instance %d index %d\n", instance_index, audio_instances[instance_index].audio_index);
|
||||||
|
|
||||||
|
for (int i = instance_index; i < (audio_instances_count - 1); i++) {
|
||||||
|
audio_instances[i] = audio_instances[i + 1];
|
||||||
|
}
|
||||||
|
audio_instances_count -= 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline void update_instance(int16_t * mix_buffer, AudioInstance & instance)
|
||||||
|
{
|
||||||
int16_t const * const buf = instance.audio_buffer->buf;
|
int16_t const * const buf = instance.audio_buffer->buf;
|
||||||
uint32_t const sample_count = instance.audio_buffer->sample_count;
|
uint32_t const sample_count = instance.audio_buffer->sample_count;
|
||||||
uint32_t const loop_end = instance.audio_buffer->audio_file->loop_end;
|
uint32_t const loop_end = instance.audio_buffer->audio->loop_end * (double)sample_rate;
|
||||||
|
|
||||||
uint32_t mix_index = 0;
|
uint32_t mix_index = 0;
|
||||||
for (int i = 0; i < half_period_samples; i++) {
|
for (int i = 0; i < half_period_samples; i++) {
|
||||||
|
if (loop_end != 0) {
|
||||||
if (instance.sample_index >= loop_end) {
|
if (instance.sample_index >= loop_end) {
|
||||||
instance.sample_index = 0;
|
instance.sample_index = 0;
|
||||||
instance.tail_index = loop_end;
|
instance.tail_index = loop_end;
|
||||||
fprintf(stderr, "loop\n");
|
}
|
||||||
|
} else if (instance.sample_index >= sample_count) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (instance.fadeout_end != 0 && instance.fadeout_index >= instance.fadeout_end) {
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
assert(instance.sample_index < sample_count);
|
assert(instance.sample_index < sample_count);
|
||||||
assert(instance.tail_index <= sample_count);
|
assert(instance.tail_index <= sample_count);
|
||||||
|
|
||||||
for (int ch = 0; ch < channels; ch++) {
|
|
||||||
mix_buffer[mix_index * channels + ch] += buf[instance.sample_index * channels + ch];
|
double fadeout = 1.0;
|
||||||
if (instance.tail_index != sample_count) {
|
if (instance.fadeout_end != 0) {
|
||||||
mix_buffer[mix_index * channels + ch] += buf[instance.tail_index * channels + ch];
|
fadeout = 1.0 - ((double)instance.fadeout_index / (double)instance.fadeout_end);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
for (int ch = 0; ch < channels; ch++) {
|
||||||
|
int32_t value = buf[instance.sample_index * channels + ch];
|
||||||
|
if (instance.tail_index != sample_count) {
|
||||||
|
value += buf[instance.tail_index * channels + ch];
|
||||||
|
}
|
||||||
|
saturation_add(&mix_buffer[mix_index * channels + ch], (double)value * fadeout);
|
||||||
}
|
}
|
||||||
instance.sample_index += 1;
|
instance.sample_index += 1;
|
||||||
|
instance.fadeout_index += 1;
|
||||||
if (instance.tail_index != sample_count) {
|
if (instance.tail_index != sample_count) {
|
||||||
instance.tail_index += 1;
|
instance.tail_index += 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
mix_index += 1;
|
mix_index += 1;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline bool should_cull_instance(AudioInstance & instance)
|
||||||
|
{
|
||||||
|
if (instance.audio_buffer->audio->loop_end != 0.0 && instance.sample_index >= instance.audio_buffer->sample_count) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
if (instance.fadeout_end != 0 && instance.fadeout_index >= instance.fadeout_end) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
void update()
|
||||||
|
{
|
||||||
|
if (SDL_GetAudioStreamQueued(audio_stream) >= half_period_size)
|
||||||
|
return;
|
||||||
|
|
||||||
|
int16_t mix_buffer[half_period_samples * channels];
|
||||||
|
memset(mix_buffer, 0, (sizeof (mix_buffer)));
|
||||||
|
|
||||||
|
for (int i = 0; i < audio_instances_count; i++) {
|
||||||
|
update_instance(mix_buffer, audio_instances[i]);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool culled = true;
|
||||||
|
while (culled) {
|
||||||
|
culled = false;
|
||||||
|
for (int i = 0; i < audio_instances_count; i++) {
|
||||||
|
if (should_cull_instance(audio_instances[i])) {
|
||||||
|
culled = true;
|
||||||
|
remove_instance(i);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
SDL_PutAudioStreamData(audio_stream, (void *)mix_buffer, half_period_size);
|
SDL_PutAudioStreamData(audio_stream, (void *)mix_buffer, half_period_size);
|
||||||
*/
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -4,6 +4,8 @@
|
|||||||
#include "renpy/script.h"
|
#include "renpy/script.h"
|
||||||
#include "renpy/interpreter.h"
|
#include "renpy/interpreter.h"
|
||||||
|
|
||||||
|
#include "audio.h"
|
||||||
|
|
||||||
namespace renpy {
|
namespace renpy {
|
||||||
void interpreter::reset()
|
void interpreter::reset()
|
||||||
{
|
{
|
||||||
@ -64,7 +66,12 @@ namespace renpy {
|
|||||||
|
|
||||||
switch (statement.type) {
|
switch (statement.type) {
|
||||||
case language::type::play:
|
case language::type::play:
|
||||||
fprintf(stderr, "interpret_one[%d]: play\n", pc);
|
fprintf(stderr, "interpret_one[%d]: play %d\n", pc, statement.play.audioIndex);
|
||||||
|
audio::play(statement.play.audioIndex);
|
||||||
|
pc += 1;
|
||||||
|
break;
|
||||||
|
case language::type::stop:
|
||||||
|
audio::stop(statement.stop.audioIndex, statement.stop.fadeout);
|
||||||
pc += 1;
|
pc += 1;
|
||||||
break;
|
break;
|
||||||
case language::type::scene_color:
|
case language::type::scene_color:
|
||||||
|
|||||||
@ -194,14 +194,14 @@ const language::character characters[] = {
|
|||||||
const int characters_length = (sizeof (characters)) / (sizeof (characters[0]));
|
const int characters_length = (sizeof (characters)) / (sizeof (characters[0]));
|
||||||
|
|
||||||
const language::audio audio[] = {
|
const language::audio audio[] = {
|
||||||
{ .path = "audio/sfx/Chime.opus.bin", .name = "sound", .loop = 0 }, // 0 sfx/Chime.ogg
|
{ .path = "audio/sfx/Chime.opus.bin", .loop_end = 0.0 }, // 0 sfx/Chime.ogg
|
||||||
{ .path = "audio/sfx/MistAmbience.opus.bin", .name = "MistAmbience", .loop = 1056000 }, // 1 sfx/MistAmbience.ogg
|
{ .path = "audio/sfx/MistAmbience.opus.bin", .loop_end = 22.0 }, // 1 sfx/MistAmbience.ogg
|
||||||
{ .path = "audio/music/TinyForestMinstrels.opus.bin", .name = "TinyForestMinstrels", .loop = 2112000 }, // 2 music/TinyForestMinstrels.ogg
|
{ .path = "audio/music/TinyForestMinstrels.opus.bin", .loop_end = 44.0 }, // 2 music/TinyForestMinstrels.ogg
|
||||||
{ .path = "audio/music/PhrygianButterflies.opus.bin", .name = "PhrygianButterflies", .loop = 1926000 }, // 3 music/PhrygianButterflies.ogg
|
{ .path = "audio/music/PhrygianButterflies.opus.bin", .loop_end = 40.125 }, // 3 music/PhrygianButterflies.ogg
|
||||||
{ .path = "audio/music/Poem1.opus.bin", .name = "music", .loop = 0 }, // 4 music/Poem1.ogg
|
{ .path = "audio/music/Poem1.opus.bin", .loop_end = 0.0 }, // 4 music/Poem1.ogg
|
||||||
{ .path = "audio/placeholdermeow.opus.bin", .name = nullptr, .loop = 0 }, // 5 placeholdermeow.mp3
|
{ .path = "audio/placeholdermeow.opus.bin", .loop_end = 0.0 }, // 5 placeholdermeow.mp3
|
||||||
{ .path = "audio/music/ScaredMice.opus.bin", .name = "ScaredMice", .loop = 384000 }, // 6 music/ScaredMice.ogg
|
{ .path = "audio/music/ScaredMice.opus.bin", .loop_end = 8.0 }, // 6 music/ScaredMice.ogg
|
||||||
{ .path = "audio/music/WheatFields.opus.bin", .name = "WheatFields", .loop = 1632000 }, // 7 music/WheatFields.ogg
|
{ .path = "audio/music/WheatFields.opus.bin", .loop_end = 34.0 }, // 7 music/WheatFields.ogg
|
||||||
};
|
};
|
||||||
|
|
||||||
const int audio_length = (sizeof (audio)) / (sizeof (audio[0]));
|
const int audio_length = (sizeof (audio)) / (sizeof (audio[0]));
|
||||||
@ -221,12 +221,12 @@ const language::image images[] = {
|
|||||||
const int images_length = (sizeof (images)) / (sizeof (images[0]));
|
const int images_length = (sizeof (images)) / (sizeof (images[0]));
|
||||||
|
|
||||||
const language::option options[] = {
|
const language::option options[] = {
|
||||||
{ .string = "Complain", .statementIndex = 18 }, // 0
|
{ .string = "Complain", .statementIndex = 19 }, // 0
|
||||||
{ .string = "Rationalize", .statementIndex = 26 }, // 1
|
{ .string = "Rationalize", .statementIndex = 27 }, // 1
|
||||||
{ .string = "Good idea", .statementIndex = 53 }, // 2
|
{ .string = "Good idea", .statementIndex = 54 }, // 2
|
||||||
{ .string = "I am too tired", .statementIndex = 60 }, // 3
|
{ .string = "I am too tired", .statementIndex = 61 }, // 3
|
||||||
{ .string = "Beg for mercy", .statementIndex = 77 }, // 4
|
{ .string = "Beg for mercy", .statementIndex = 78 }, // 4
|
||||||
{ .string = "Run", .statementIndex = 79 }, // 5
|
{ .string = "Run", .statementIndex = 80 }, // 5
|
||||||
};
|
};
|
||||||
|
|
||||||
const int options_length = (sizeof (options)) / (sizeof (options[0]));
|
const int options_length = (sizeof (options)) / (sizeof (options[0]));
|
||||||
@ -241,244 +241,245 @@ const language::statement statements[] = {
|
|||||||
{ .type = type::say, .say = { .characterIndex = 4, .stringIndex = 2 } }, // 6 n "And across the vast fields of Alysen"
|
{ .type = type::say, .say = { .characterIndex = 4, .stringIndex = 2 } }, // 6 n "And across the vast fields of Alysen"
|
||||||
{ .type = type::play, .play = { .audioIndex = 2 } }, // 7 music/TinyForestMinstrels.ogg
|
{ .type = type::play, .play = { .audioIndex = 2 } }, // 7 music/TinyForestMinstrels.ogg
|
||||||
{ .type = type::say, .say = { .characterIndex = 4, .stringIndex = 3 } }, // 8 n "Tiny minstrels can be heard amongst the trees"
|
{ .type = type::say, .say = { .characterIndex = 4, .stringIndex = 3 } }, // 8 n "Tiny minstrels can be heard amongst the trees"
|
||||||
{ .type = type::scene, .scene = { .imageIndex = 1 } }, // 9 bgforest1
|
{ .type = type::stop, .stop = { .audioIndex = 2, .fadeout = 5.5 } }, // 9 TinyForestMinstrels
|
||||||
{ .type = type::dissolve, .dissolve = { .duration = 3.0 } }, // 10
|
{ .type = type::scene, .scene = { .imageIndex = 1 } }, // 10 bgforest1
|
||||||
{ .type = type::show, .show = { .imageIndex = 8, .transformIndex = transform::left } }, // 11 al
|
{ .type = type::dissolve, .dissolve = { .duration = 3.0 } }, // 11
|
||||||
{ .type = type::say, .say = { .characterIndex = 0, .stringIndex = 4 } }, // 12 a "Are we almost there?"
|
{ .type = type::show, .show = { .imageIndex = 8, .transformIndex = transform::left } }, // 12 al
|
||||||
{ .type = type::show, .show = { .imageIndex = 7, .transformIndex = transform::right } }, // 13 ei
|
{ .type = type::say, .say = { .characterIndex = 0, .stringIndex = 4 } }, // 13 a "Are we almost there?"
|
||||||
{ .type = type::say, .say = { .characterIndex = 2, .stringIndex = 5 } }, // 14 e "Hmmm... Not really"
|
{ .type = type::show, .show = { .imageIndex = 7, .transformIndex = transform::right } }, // 14 ei
|
||||||
{ .type = type::say, .say = { .characterIndex = 0, .stringIndex = 6 } }, // 15 a "How much further have we to go?"
|
{ .type = type::say, .say = { .characterIndex = 2, .stringIndex = 5 } }, // 15 e "Hmmm... Not really"
|
||||||
{ .type = type::say, .say = { .characterIndex = 2, .stringIndex = 7 } }, // 16 e "About two more moons"
|
{ .type = type::say, .say = { .characterIndex = 0, .stringIndex = 6 } }, // 16 a "How much further have we to go?"
|
||||||
{ .type = type::menu, .menu = { .count = 2, .optionIndex = 0 } }, // 17 "Complain", "Rationalize"
|
{ .type = type::say, .say = { .characterIndex = 2, .stringIndex = 7 } }, // 17 e "About two more moons"
|
||||||
{ .type = type::say, .say = { .characterIndex = 0, .stringIndex = 8 } }, // 18 a "We are still sooo far awayyy"
|
{ .type = type::menu, .menu = { .count = 2, .optionIndex = 0 } }, // 18 "Complain", "Rationalize"
|
||||||
{ .type = type::say, .say = { .characterIndex = 2, .stringIndex = 9 } }, // 19 e "And it will be even further if you dont stop complaining"
|
{ .type = type::say, .say = { .characterIndex = 0, .stringIndex = 8 } }, // 19 a "We are still sooo far awayyy"
|
||||||
{ .type = type::say, .say = { .characterIndex = 0, .stringIndex = 10 } }, // 20 a "Easy for you to say, all you have to carry is a little memory pipe!"
|
{ .type = type::say, .say = { .characterIndex = 2, .stringIndex = 9 } }, // 20 e "And it will be even further if you dont stop complaining"
|
||||||
{ .type = type::say, .say = { .characterIndex = 0, .stringIndex = 11 } }, // 21 a "I'm tired ><"
|
{ .type = type::say, .say = { .characterIndex = 0, .stringIndex = 10 } }, // 21 a "Easy for you to say, all you have to carry is a little memory pipe!"
|
||||||
{ .type = type::say, .say = { .characterIndex = 2, .stringIndex = 12 } }, // 22 e "Don't start whining now!"
|
{ .type = type::say, .say = { .characterIndex = 0, .stringIndex = 11 } }, // 22 a "I'm tired ><"
|
||||||
{ .type = type::say, .say = { .characterIndex = 2, .stringIndex = 13 } }, // 23 e "You need to remember why we have come all this way"
|
{ .type = type::say, .say = { .characterIndex = 2, .stringIndex = 12 } }, // 23 e "Don't start whining now!"
|
||||||
{ .type = type::say, .say = { .characterIndex = 0, .stringIndex = 14 } }, // 24 a "I understand... I suppose it is for an important purpose"
|
{ .type = type::say, .say = { .characterIndex = 2, .stringIndex = 13 } }, // 24 e "You need to remember why we have come all this way"
|
||||||
{ .type = type::jump, .jump = { .statementIndex = 28 } }, // 25 internal jump (b'__menu_end', 0)
|
{ .type = type::say, .say = { .characterIndex = 0, .stringIndex = 14 } }, // 25 a "I understand... I suppose it is for an important purpose"
|
||||||
{ .type = type::say, .say = { .characterIndex = 0, .stringIndex = 14 } }, // 26 a "I understand... I suppose it is for an important purpose"
|
{ .type = type::jump, .jump = { .statementIndex = 29 } }, // 26 internal jump (b'__menu_end', 0)
|
||||||
{ .type = type::jump, .jump = { .statementIndex = 28 } }, // 27 internal jump (b'__menu_end', 0)
|
{ .type = type::say, .say = { .characterIndex = 0, .stringIndex = 14 } }, // 27 a "I understand... I suppose it is for an important purpose"
|
||||||
{ .type = type::jump, .jump = { .statementIndex = 29 } }, // 28 mainbranch1
|
{ .type = type::jump, .jump = { .statementIndex = 29 } }, // 28 internal jump (b'__menu_end', 0)
|
||||||
{ .type = type::say, .say = { .characterIndex = 2, .stringIndex = 15 } }, // 29 e "We're almost out of the forest, we can take a little break once we clear the tree line"
|
{ .type = type::jump, .jump = { .statementIndex = 30 } }, // 29 mainbranch1
|
||||||
{ .type = type::say, .say = { .characterIndex = 0, .stringIndex = 16 } }, // 30 a "Is that where the flora field is?"
|
{ .type = type::say, .say = { .characterIndex = 2, .stringIndex = 15 } }, // 30 e "We're almost out of the forest, we can take a little break once we clear the tree line"
|
||||||
{ .type = type::say, .say = { .characterIndex = 2, .stringIndex = 17 } }, // 31 e "Why yes, If I remember correctly, it should be just up ahead"
|
{ .type = type::say, .say = { .characterIndex = 0, .stringIndex = 16 } }, // 31 a "Is that where the flora field is?"
|
||||||
{ .type = type::stop, .stop = { /* FIXME channel */ } }, // 32
|
{ .type = type::say, .say = { .characterIndex = 2, .stringIndex = 17 } }, // 32 e "Why yes, If I remember correctly, it should be just up ahead"
|
||||||
{ .type = type::scene_color, .scene_color = { .color = 0xffffff } }, // 33 bgwhite
|
{ .type = type::stop, .stop = { .audioIndex = 2, .fadeout = 5.5 } }, // 33 TinyForestMinstrels
|
||||||
{ .type = type::play, .play = { .audioIndex = 0 } }, // 34 sfx/Chime.ogg
|
{ .type = type::scene_color, .scene_color = { .color = 0xffffff } }, // 34 bgwhite
|
||||||
{ .type = type::dissolve, .dissolve = { .duration = 1.0 } }, // 35
|
{ .type = type::play, .play = { .audioIndex = 0 } }, // 35 sfx/Chime.ogg
|
||||||
{ .type = type::say, .say = { .characterIndex = 4, .stringIndex = 18 } }, // 36 n "As the minstrel mice girls continue along the path, the forest opens up into a beautiful field of flowers"
|
{ .type = type::dissolve, .dissolve = { .duration = 1.0 } }, // 36
|
||||||
{ .type = type::play, .play = { .audioIndex = 3 } }, // 37 music/PhrygianButterflies.ogg
|
{ .type = type::say, .say = { .characterIndex = 4, .stringIndex = 18 } }, // 37 n "As the minstrel mice girls continue along the path, the forest opens up into a beautiful field of flowers"
|
||||||
{ .type = type::scene, .scene = { .imageIndex = 3 } }, // 38 bgflower1
|
{ .type = type::play, .play = { .audioIndex = 3 } }, // 38 music/PhrygianButterflies.ogg
|
||||||
{ .type = type::dissolve, .dissolve = { .duration = 1.0 } }, // 39
|
{ .type = type::scene, .scene = { .imageIndex = 3 } }, // 39 bgflower1
|
||||||
{ .type = type::show, .show = { .imageIndex = 7, .transformIndex = transform::right } }, // 40 ei
|
{ .type = type::dissolve, .dissolve = { .duration = 1.0 } }, // 40
|
||||||
{ .type = type::say, .say = { .characterIndex = 2, .stringIndex = 19 } }, // 41 e "Look at all the butterflies! They are all so pretty!"
|
{ .type = type::show, .show = { .imageIndex = 7, .transformIndex = transform::right } }, // 41 ei
|
||||||
{ .type = type::show, .show = { .imageIndex = 8, .transformIndex = transform::left } }, // 42 al
|
{ .type = type::say, .say = { .characterIndex = 2, .stringIndex = 19 } }, // 42 e "Look at all the butterflies! They are all so pretty!"
|
||||||
{ .type = type::say, .say = { .characterIndex = 0, .stringIndex = 20 } }, // 43 a "This place is like a dream..."
|
{ .type = type::show, .show = { .imageIndex = 8, .transformIndex = transform::left } }, // 43 al
|
||||||
{ .type = type::say, .say = { .characterIndex = 2, .stringIndex = 21 } }, // 44 e "There are so many flowers this time of year"
|
{ .type = type::say, .say = { .characterIndex = 0, .stringIndex = 20 } }, // 44 a "This place is like a dream..."
|
||||||
{ .type = type::say, .say = { .characterIndex = 2, .stringIndex = 22 } }, // 45 e "I told you it would be worth the journey!"
|
{ .type = type::say, .say = { .characterIndex = 2, .stringIndex = 21 } }, // 45 e "There are so many flowers this time of year"
|
||||||
{ .type = type::say, .say = { .characterIndex = 0, .stringIndex = 23 } }, // 46 a "Can we stop for a bit now?"
|
{ .type = type::say, .say = { .characterIndex = 2, .stringIndex = 22 } }, // 46 e "I told you it would be worth the journey!"
|
||||||
{ .type = type::say, .say = { .characterIndex = 2, .stringIndex = 24 } }, // 47 e "Of course"
|
{ .type = type::say, .say = { .characterIndex = 0, .stringIndex = 23 } }, // 47 a "Can we stop for a bit now?"
|
||||||
{ .type = type::say, .say = { .characterIndex = 2, .stringIndex = 25 } }, // 48 e "Ya know, Its a shame we didnt save some of those giant strawberries you found"
|
{ .type = type::say, .say = { .characterIndex = 2, .stringIndex = 24 } }, // 48 e "Of course"
|
||||||
{ .type = type::say, .say = { .characterIndex = 0, .stringIndex = 26 } }, // 49 a "I told you not to eat them all!"
|
{ .type = type::say, .say = { .characterIndex = 2, .stringIndex = 25 } }, // 49 e "Ya know, Its a shame we didnt save some of those giant strawberries you found"
|
||||||
{ .type = type::say, .say = { .characterIndex = 2, .stringIndex = 27 } }, // 50 e "Yah yah"
|
{ .type = type::say, .say = { .characterIndex = 0, .stringIndex = 26 } }, // 50 a "I told you not to eat them all!"
|
||||||
{ .type = type::say, .say = { .characterIndex = 2, .stringIndex = 28 } }, // 51 e "Anyways, shall I recite a tale?"
|
{ .type = type::say, .say = { .characterIndex = 2, .stringIndex = 27 } }, // 51 e "Yah yah"
|
||||||
{ .type = type::menu, .menu = { .count = 2, .optionIndex = 2 } }, // 52 "Good idea", "I am too tired"
|
{ .type = type::say, .say = { .characterIndex = 2, .stringIndex = 28 } }, // 52 e "Anyways, shall I recite a tale?"
|
||||||
{ .type = type::stop, .stop = { /* FIXME channel */ } }, // 53
|
{ .type = type::menu, .menu = { .count = 2, .optionIndex = 2 } }, // 53 "Good idea", "I am too tired"
|
||||||
{ .type = type::say, .say = { .characterIndex = 0, .stringIndex = 29 } }, // 54 a "Why dont you sing the story of Eleanor the Hero!"
|
{ .type = type::stop, .stop = { .audioIndex = 3, .fadeout = 4.2 } }, // 54 PhrygianButterflies
|
||||||
{ .type = type::say, .say = { .characterIndex = 2, .stringIndex = 30 } }, // 55 e "Sure"
|
{ .type = type::say, .say = { .characterIndex = 0, .stringIndex = 29 } }, // 55 a "Why dont you sing the story of Eleanor the Hero!"
|
||||||
{ .type = type::say, .say = { .characterIndex = 0, .stringIndex = 31 } }, // 56 a "..."
|
{ .type = type::say, .say = { .characterIndex = 2, .stringIndex = 30 } }, // 56 e "Sure"
|
||||||
{ .type = type::play, .play = { .audioIndex = 4 } }, // 57 music/Poem1.ogg
|
{ .type = type::say, .say = { .characterIndex = 0, .stringIndex = 31 } }, // 57 a "..."
|
||||||
{ .type = type::pause, .pause = { .duration = 40 } }, // 58
|
{ .type = type::play, .play = { .audioIndex = 4 } }, // 58 music/Poem1.ogg
|
||||||
{ .type = type::jump, .jump = { .statementIndex = 64 } }, // 59 internal jump (b'__menu_end', 1)
|
{ .type = type::pause, .pause = { .duration = 40 } }, // 59
|
||||||
{ .type = type::say, .say = { .characterIndex = 2, .stringIndex = 32 } }, // 60 e "Serves you right for scaring those elephant-dogs"
|
{ .type = type::jump, .jump = { .statementIndex = 65 } }, // 60 internal jump (b'__menu_end', 1)
|
||||||
{ .type = type::stop, .stop = { /* FIXME channel */ } }, // 61
|
{ .type = type::say, .say = { .characterIndex = 2, .stringIndex = 32 } }, // 61 e "Serves you right for scaring those elephant-dogs"
|
||||||
{ .type = type::say, .say = { .characterIndex = 0, .stringIndex = 33 } }, // 62 a "They were asking for it, you know"
|
{ .type = type::stop, .stop = { .audioIndex = 3, .fadeout = 4.2 } }, // 62 PhrygianButterflies
|
||||||
{ .type = type::jump, .jump = { .statementIndex = 64 } }, // 63 internal jump (b'__menu_end', 1)
|
{ .type = type::say, .say = { .characterIndex = 0, .stringIndex = 33 } }, // 63 a "They were asking for it, you know"
|
||||||
{ .type = type::jump, .jump = { .statementIndex = 65 } }, // 64 mainbranch2
|
{ .type = type::jump, .jump = { .statementIndex = 65 } }, // 64 internal jump (b'__menu_end', 1)
|
||||||
{ .type = type::hide, .hide = { .imageIndex = 7 } }, // 65 ei
|
{ .type = type::jump, .jump = { .statementIndex = 66 } }, // 65 mainbranch2
|
||||||
{ .type = type::show, .show = { .imageIndex = 6, .transformIndex = transform::right } }, // 66 catw
|
{ .type = type::hide, .hide = { .imageIndex = 7 } }, // 66 ei
|
||||||
{ .type = type::show, .show = { .imageIndex = 7, .transformIndex = transform::centerleft } }, // 67 ei
|
{ .type = type::show, .show = { .imageIndex = 6, .transformIndex = transform::right } }, // 67 catw
|
||||||
{ .type = type::voice, .voice = { .audioIndex = 5 } }, // 68 placeholdermeow.mp3
|
{ .type = type::show, .show = { .imageIndex = 7, .transformIndex = transform::centerleft } }, // 68 ei
|
||||||
{ .type = type::say, .say = { .characterIndex = 1, .stringIndex = 34 } }, // 69 c "Rawrrrr"
|
{ .type = type::voice, .voice = { .audioIndex = 5 } }, // 69 placeholdermeow.mp3
|
||||||
{ .type = type::hide, .hide = { .imageIndex = 6 } }, // 70 catw
|
{ .type = type::say, .say = { .characterIndex = 1, .stringIndex = 34 } }, // 70 c "Rawrrrr"
|
||||||
{ .type = type::show, .show = { .imageIndex = 5, .transformIndex = transform::right } }, // 71 cat
|
{ .type = type::hide, .hide = { .imageIndex = 6 } }, // 71 catw
|
||||||
{ .type = type::play, .play = { .audioIndex = 6 } }, // 72 music/ScaredMice.ogg
|
{ .type = type::show, .show = { .imageIndex = 5, .transformIndex = transform::right } }, // 72 cat
|
||||||
{ .type = type::say, .say = { .characterIndex = 3, .stringIndex = 35 } }, // 73 mg "AHHHHHHHHHH!!!!!"
|
{ .type = type::play, .play = { .audioIndex = 6 } }, // 73 music/ScaredMice.ogg
|
||||||
{ .type = type::say, .say = { .characterIndex = 1, .stringIndex = 36 } }, // 74 c "Nyanyanyanya"
|
{ .type = type::say, .say = { .characterIndex = 3, .stringIndex = 35 } }, // 74 mg "AHHHHHHHHHH!!!!!"
|
||||||
{ .type = type::say, .say = { .characterIndex = 1, .stringIndex = 37 } }, // 75 c "Well, what do we have here? If it isn't two little meowse girls, all alone amongst the flowers"
|
{ .type = type::say, .say = { .characterIndex = 1, .stringIndex = 36 } }, // 75 c "Nyanyanyanya"
|
||||||
{ .type = type::menu, .menu = { .count = 2, .optionIndex = 4 } }, // 76 "Beg for mercy", "Run"
|
{ .type = type::say, .say = { .characterIndex = 1, .stringIndex = 37 } }, // 76 c "Well, what do we have here? If it isn't two little meowse girls, all alone amongst the flowers"
|
||||||
{ .type = type::say, .say = { .characterIndex = 0, .stringIndex = 38 } }, // 77 a "Please don't eat us!!!"
|
{ .type = type::menu, .menu = { .count = 2, .optionIndex = 4 } }, // 77 "Beg for mercy", "Run"
|
||||||
{ .type = type::jump, .jump = { .statementIndex = 82 } }, // 78 internal jump (b'__menu_end', 2)
|
{ .type = type::say, .say = { .characterIndex = 0, .stringIndex = 38 } }, // 78 a "Please don't eat us!!!"
|
||||||
{ .type = type::say, .say = { .characterIndex = 2, .stringIndex = 39 } }, // 79 e "Alice don't run, our only chance is through pleading!"
|
{ .type = type::jump, .jump = { .statementIndex = 83 } }, // 79 internal jump (b'__menu_end', 2)
|
||||||
{ .type = type::say, .say = { .characterIndex = 2, .stringIndex = 40 } }, // 80 e "Please don't eat us, miss kitty cat!!! ><"
|
{ .type = type::say, .say = { .characterIndex = 2, .stringIndex = 39 } }, // 80 e "Alice don't run, our only chance is through pleading!"
|
||||||
{ .type = type::jump, .jump = { .statementIndex = 82 } }, // 81 internal jump (b'__menu_end', 2)
|
{ .type = type::say, .say = { .characterIndex = 2, .stringIndex = 40 } }, // 81 e "Please don't eat us, miss kitty cat!!! ><"
|
||||||
{ .type = type::jump, .jump = { .statementIndex = 83 } }, // 82 mainbranch3
|
{ .type = type::jump, .jump = { .statementIndex = 83 } }, // 82 internal jump (b'__menu_end', 2)
|
||||||
{ .type = type::stop, .stop = { /* FIXME channel */ } }, // 83
|
{ .type = type::jump, .jump = { .statementIndex = 84 } }, // 83 mainbranch3
|
||||||
{ .type = type::say, .say = { .characterIndex = 1, .stringIndex = 41 } }, // 84 c "I'm not gonna eat you nyanyanya"
|
{ .type = type::stop, .stop = { .audioIndex = 6, .fadeout = 2.0 } }, // 84 ScaredMice
|
||||||
{ .type = type::play, .play = { .audioIndex = 2 } }, // 85 music/TinyForestMinstrels.ogg
|
{ .type = type::say, .say = { .characterIndex = 1, .stringIndex = 41 } }, // 85 c "I'm not gonna eat you nyanyanya"
|
||||||
{ .type = type::say, .say = { .characterIndex = 1, .stringIndex = 42 } }, // 86 c "I just want to know what two little meowses are doing so very far away from home"
|
{ .type = type::play, .play = { .audioIndex = 2 } }, // 86 music/TinyForestMinstrels.ogg
|
||||||
{ .type = type::say, .say = { .characterIndex = 1, .stringIndex = 43 } }, // 87 c "Also, are you minstrels?"
|
{ .type = type::say, .say = { .characterIndex = 1, .stringIndex = 42 } }, // 87 c "I just want to know what two little meowses are doing so very far away from home"
|
||||||
{ .type = type::say, .say = { .characterIndex = 2, .stringIndex = 44 } }, // 88 e "Y-Yes"
|
{ .type = type::say, .say = { .characterIndex = 1, .stringIndex = 43 } }, // 88 c "Also, are you minstrels?"
|
||||||
{ .type = type::say, .say = { .characterIndex = 0, .stringIndex = 45 } }, // 89 a "W-We are on a quest to Castle Alysen..."
|
{ .type = type::say, .say = { .characterIndex = 2, .stringIndex = 44 } }, // 89 e "Y-Yes"
|
||||||
{ .type = type::say, .say = { .characterIndex = 2, .stringIndex = 46 } }, // 90 e "Shh don't tell her that"
|
{ .type = type::say, .say = { .characterIndex = 0, .stringIndex = 45 } }, // 90 a "W-We are on a quest to Castle Alysen..."
|
||||||
{ .type = type::say, .say = { .characterIndex = 1, .stringIndex = 47 } }, // 91 c "The Castle of Alysen you say?!?"
|
{ .type = type::say, .say = { .characterIndex = 2, .stringIndex = 46 } }, // 91 e "Shh don't tell her that"
|
||||||
{ .type = type::say, .say = { .characterIndex = 1, .stringIndex = 48 } }, // 92 c "Why, that's where I am headed!"
|
{ .type = type::say, .say = { .characterIndex = 1, .stringIndex = 47 } }, // 92 c "The Castle of Alysen you say?!?"
|
||||||
{ .type = type::say, .say = { .characterIndex = 2, .stringIndex = 49 } }, // 93 e "You don't say..."
|
{ .type = type::say, .say = { .characterIndex = 1, .stringIndex = 48 } }, // 93 c "Why, that's where I am headed!"
|
||||||
{ .type = type::say, .say = { .characterIndex = 1, .stringIndex = 50 } }, // 94 c "Yah, I do actually"
|
{ .type = type::say, .say = { .characterIndex = 2, .stringIndex = 49 } }, // 94 e "You don't say..."
|
||||||
{ .type = type::say, .say = { .characterIndex = 2, .stringIndex = 51 } }, // 95 e "So... Why might you be traveling to the castle?"
|
{ .type = type::say, .say = { .characterIndex = 1, .stringIndex = 50 } }, // 95 c "Yah, I do actually"
|
||||||
{ .type = type::say, .say = { .characterIndex = 1, .stringIndex = 52 } }, // 96 c "I belong to the lineage of Agrepen"
|
{ .type = type::say, .say = { .characterIndex = 2, .stringIndex = 51 } }, // 96 e "So... Why might you be traveling to the castle?"
|
||||||
{ .type = type::say, .say = { .characterIndex = 2, .stringIndex = 53 } }, // 97 e "And what might that mean?"
|
{ .type = type::say, .say = { .characterIndex = 1, .stringIndex = 52 } }, // 97 c "I belong to the lineage of Agrepen"
|
||||||
{ .type = type::say, .say = { .characterIndex = 1, .stringIndex = 54 } }, // 98 c "The Agrepens are a long line of felines loyal to the crown of corvidae"
|
{ .type = type::say, .say = { .characterIndex = 2, .stringIndex = 53 } }, // 98 e "And what might that mean?"
|
||||||
{ .type = type::say, .say = { .characterIndex = 2, .stringIndex = 55 } }, // 99 e "Really? That must mean you are a noble?"
|
{ .type = type::say, .say = { .characterIndex = 1, .stringIndex = 54 } }, // 99 c "The Agrepens are a long line of felines loyal to the crown of corvidae"
|
||||||
{ .type = type::say, .say = { .characterIndex = 1, .stringIndex = 56 } }, // 100 c "Well, not really..."
|
{ .type = type::say, .say = { .characterIndex = 2, .stringIndex = 55 } }, // 100 e "Really? That must mean you are a noble?"
|
||||||
{ .type = type::say, .say = { .characterIndex = 1, .stringIndex = 57 } }, // 101 c "My father was one of the queens knights many years ago"
|
{ .type = type::say, .say = { .characterIndex = 1, .stringIndex = 56 } }, // 101 c "Well, not really..."
|
||||||
{ .type = type::say, .say = { .characterIndex = 2, .stringIndex = 58 } }, // 102 e "Ah I see"
|
{ .type = type::say, .say = { .characterIndex = 1, .stringIndex = 57 } }, // 102 c "My father was one of the queens knights many years ago"
|
||||||
{ .type = type::say, .say = { .characterIndex = 2, .stringIndex = 59 } }, // 103 e "So do you live at the castle or something?"
|
{ .type = type::say, .say = { .characterIndex = 2, .stringIndex = 58 } }, // 103 e "Ah I see"
|
||||||
{ .type = type::say, .say = { .characterIndex = 1, .stringIndex = 60 } }, // 104 c "Well, no..."
|
{ .type = type::say, .say = { .characterIndex = 2, .stringIndex = 59 } }, // 104 e "So do you live at the castle or something?"
|
||||||
{ .type = type::say, .say = { .characterIndex = 0, .stringIndex = 61 } }, // 105 a "Then why are you traveling to Castle Alysen?"
|
{ .type = type::say, .say = { .characterIndex = 1, .stringIndex = 60 } }, // 105 c "Well, no..."
|
||||||
{ .type = type::say, .say = { .characterIndex = 1, .stringIndex = 62 } }, // 106 c "uhhh"
|
{ .type = type::say, .say = { .characterIndex = 0, .stringIndex = 61 } }, // 106 a "Then why are you traveling to Castle Alysen?"
|
||||||
{ .type = type::play, .play = { .audioIndex = 1 } }, // 107 sfx/MistAmbience.ogg
|
{ .type = type::say, .say = { .characterIndex = 1, .stringIndex = 62 } }, // 107 c "uhhh"
|
||||||
{ .type = type::stop, .stop = { /* FIXME channel */ } }, // 108
|
{ .type = type::play, .play = { .audioIndex = 1 } }, // 108 sfx/MistAmbience.ogg
|
||||||
{ .type = type::say, .say = { .characterIndex = 1, .stringIndex = 63 } }, // 109 c "I DONT NEED TO BE PRESSURED BY LITTLE MICE TO SAY ANYTHING!!!!"
|
{ .type = type::stop, .stop = { .audioIndex = 2, .fadeout = 2.0 } }, // 109 TinyForestMinstrels
|
||||||
{ .type = type::say, .say = { .characterIndex = 1, .stringIndex = 64 } }, // 110 c "GOOD DAY!"
|
{ .type = type::say, .say = { .characterIndex = 1, .stringIndex = 63 } }, // 110 c "I DONT NEED TO BE PRESSURED BY LITTLE MICE TO SAY ANYTHING!!!!"
|
||||||
{ .type = type::hide, .hide = { .imageIndex = 5 } }, // 111 cat
|
{ .type = type::say, .say = { .characterIndex = 1, .stringIndex = 64 } }, // 111 c "GOOD DAY!"
|
||||||
{ .type = type::say, .say = { .characterIndex = 0, .stringIndex = 65 } }, // 112 a "Wha..."
|
{ .type = type::hide, .hide = { .imageIndex = 5 } }, // 112 cat
|
||||||
{ .type = type::say, .say = { .characterIndex = 2, .stringIndex = 66 } }, // 113 e "Phew, I was scared she was gonna follow us the whole way"
|
{ .type = type::say, .say = { .characterIndex = 0, .stringIndex = 65 } }, // 113 a "Wha..."
|
||||||
{ .type = type::say, .say = { .characterIndex = 0, .stringIndex = 67 } }, // 114 a "She didn't seem so bad"
|
{ .type = type::say, .say = { .characterIndex = 2, .stringIndex = 66 } }, // 114 e "Phew, I was scared she was gonna follow us the whole way"
|
||||||
{ .type = type::say, .say = { .characterIndex = 2, .stringIndex = 68 } }, // 115 e "Are you kidding? She's a crazy kitty!"
|
{ .type = type::say, .say = { .characterIndex = 0, .stringIndex = 67 } }, // 115 a "She didn't seem so bad"
|
||||||
{ .type = type::scene_color, .scene_color = { .color = 0xffffff } }, // 116 bgwhite
|
{ .type = type::say, .say = { .characterIndex = 2, .stringIndex = 68 } }, // 116 e "Are you kidding? She's a crazy kitty!"
|
||||||
{ .type = type::play, .play = { .audioIndex = 0 } }, // 117 sfx/Chime.ogg
|
{ .type = type::scene_color, .scene_color = { .color = 0xffffff } }, // 117 bgwhite
|
||||||
{ .type = type::dissolve, .dissolve = { .duration = 3.0 } }, // 118
|
{ .type = type::play, .play = { .audioIndex = 0 } }, // 118 sfx/Chime.ogg
|
||||||
{ .type = type::say, .say = { .characterIndex = 4, .stringIndex = 69 } }, // 119 n "After their encounter with the weird cat, the mice scurry out of the flower field and into the nearby meadow"
|
{ .type = type::dissolve, .dissolve = { .duration = 3.0 } }, // 119
|
||||||
{ .type = type::scene, .scene = { .imageIndex = 2 } }, // 120 bgforest2
|
{ .type = type::say, .say = { .characterIndex = 4, .stringIndex = 69 } }, // 120 n "After their encounter with the weird cat, the mice scurry out of the flower field and into the nearby meadow"
|
||||||
{ .type = type::dissolve, .dissolve = { .duration = 3.0 } }, // 121
|
{ .type = type::scene, .scene = { .imageIndex = 2 } }, // 121 bgforest2
|
||||||
{ .type = type::show, .show = { .imageIndex = 7, .transformIndex = transform::right } }, // 122 ei
|
{ .type = type::dissolve, .dissolve = { .duration = 3.0 } }, // 122
|
||||||
{ .type = type::say, .say = { .characterIndex = 2, .stringIndex = 70 } }, // 123 e "I think this is the right way..."
|
{ .type = type::show, .show = { .imageIndex = 7, .transformIndex = transform::right } }, // 123 ei
|
||||||
{ .type = type::show, .show = { .imageIndex = 8, .transformIndex = transform::left } }, // 124 al
|
{ .type = type::say, .say = { .characterIndex = 2, .stringIndex = 70 } }, // 124 e "I think this is the right way..."
|
||||||
{ .type = type::say, .say = { .characterIndex = 0, .stringIndex = 71 } }, // 125 a "Then where did the path go?"
|
{ .type = type::show, .show = { .imageIndex = 8, .transformIndex = transform::left } }, // 125 al
|
||||||
{ .type = type::say, .say = { .characterIndex = 2, .stringIndex = 72 } }, // 126 e "How am I supposed to know?"
|
{ .type = type::say, .say = { .characterIndex = 0, .stringIndex = 71 } }, // 126 a "Then where did the path go?"
|
||||||
{ .type = type::say, .say = { .characterIndex = 0, .stringIndex = 73 } }, // 127 a "Did you hear that?!?!"
|
{ .type = type::say, .say = { .characterIndex = 2, .stringIndex = 72 } }, // 127 e "How am I supposed to know?"
|
||||||
{ .type = type::show, .show = { .imageIndex = 7, .transformIndex = transform::centerleft } }, // 128 ei
|
{ .type = type::say, .say = { .characterIndex = 0, .stringIndex = 73 } }, // 128 a "Did you hear that?!?!"
|
||||||
{ .type = type::show, .show = { .imageIndex = 5, .transformIndex = transform::right } }, // 129 cat
|
{ .type = type::show, .show = { .imageIndex = 7, .transformIndex = transform::centerleft } }, // 129 ei
|
||||||
{ .type = type::play, .play = { .audioIndex = 3 } }, // 130 music/PhrygianButterflies.ogg
|
{ .type = type::show, .show = { .imageIndex = 5, .transformIndex = transform::right } }, // 130 cat
|
||||||
{ .type = type::say, .say = { .characterIndex = 1, .stringIndex = 74 } }, // 131 c "Hey there..."
|
{ .type = type::play, .play = { .audioIndex = 3 } }, // 131 music/PhrygianButterflies.ogg
|
||||||
{ .type = type::say, .say = { .characterIndex = 1, .stringIndex = 75 } }, // 132 c "I apologize"
|
{ .type = type::say, .say = { .characterIndex = 1, .stringIndex = 74 } }, // 132 c "Hey there..."
|
||||||
{ .type = type::say, .say = { .characterIndex = 1, .stringIndex = 76 } }, // 133 c "I didn't mean to storm off like that"
|
{ .type = type::say, .say = { .characterIndex = 1, .stringIndex = 75 } }, // 133 c "I apologize"
|
||||||
{ .type = type::say, .say = { .characterIndex = 2, .stringIndex = 77 } }, // 134 e "Ha ha, no problem..."
|
{ .type = type::say, .say = { .characterIndex = 1, .stringIndex = 76 } }, // 134 c "I didn't mean to storm off like that"
|
||||||
{ .type = type::say, .say = { .characterIndex = 0, .stringIndex = 78 } }, // 135 a "So... Why are you traveling to Castle Alysen?"
|
{ .type = type::say, .say = { .characterIndex = 2, .stringIndex = 77 } }, // 135 e "Ha ha, no problem..."
|
||||||
{ .type = type::say, .say = { .characterIndex = 2, .stringIndex = 79 } }, // 136 e "Alice!!!"
|
{ .type = type::say, .say = { .characterIndex = 0, .stringIndex = 78 } }, // 136 a "So... Why are you traveling to Castle Alysen?"
|
||||||
{ .type = type::say, .say = { .characterIndex = 1, .stringIndex = 80 } }, // 137 c "If you must know, I have been summoned by the queen"
|
{ .type = type::say, .say = { .characterIndex = 2, .stringIndex = 79 } }, // 137 e "Alice!!!"
|
||||||
{ .type = type::say, .say = { .characterIndex = 1, .stringIndex = 81 } }, // 138 c "I suspect that my poor reputation amongst the locals of Eastern Nidus has come back to haunt me"
|
{ .type = type::say, .say = { .characterIndex = 1, .stringIndex = 80 } }, // 138 c "If you must know, I have been summoned by the queen"
|
||||||
{ .type = type::say, .say = { .characterIndex = 1, .stringIndex = 82 } }, // 139 c "Though I know not what what she has summoned me for"
|
{ .type = type::say, .say = { .characterIndex = 1, .stringIndex = 81 } }, // 139 c "I suspect that my poor reputation amongst the locals of Eastern Nidus has come back to haunt me"
|
||||||
{ .type = type::say, .say = { .characterIndex = 0, .stringIndex = 83 } }, // 140 a "Ahhhhhh"
|
{ .type = type::say, .say = { .characterIndex = 1, .stringIndex = 82 } }, // 140 c "Though I know not what what she has summoned me for"
|
||||||
{ .type = type::say, .say = { .characterIndex = 1, .stringIndex = 84 } }, // 141 c "So then..."
|
{ .type = type::say, .say = { .characterIndex = 0, .stringIndex = 83 } }, // 141 a "Ahhhhhh"
|
||||||
{ .type = type::say, .say = { .characterIndex = 1, .stringIndex = 85 } }, // 142 c "Why are YOU traveling to the Castle?"
|
{ .type = type::say, .say = { .characterIndex = 1, .stringIndex = 84 } }, // 142 c "So then..."
|
||||||
{ .type = type::say, .say = { .characterIndex = 0, .stringIndex = 86 } }, // 143 a "We are delivering a feather!!!"
|
{ .type = type::say, .say = { .characterIndex = 1, .stringIndex = 85 } }, // 143 c "Why are YOU traveling to the Castle?"
|
||||||
{ .type = type::say, .say = { .characterIndex = 2, .stringIndex = 87 } }, // 144 e "Alice no!"
|
{ .type = type::say, .say = { .characterIndex = 0, .stringIndex = 86 } }, // 144 a "We are delivering a feather!!!"
|
||||||
{ .type = type::say, .say = { .characterIndex = 0, .stringIndex = 88 } }, // 145 a "A feather that belonged to the queen herself!!!"
|
{ .type = type::say, .say = { .characterIndex = 2, .stringIndex = 87 } }, // 145 e "Alice no!"
|
||||||
{ .type = type::say, .say = { .characterIndex = 2, .stringIndex = 89 } }, // 146 e "Why you little..."
|
{ .type = type::say, .say = { .characterIndex = 0, .stringIndex = 88 } }, // 146 a "A feather that belonged to the queen herself!!!"
|
||||||
{ .type = type::say, .say = { .characterIndex = 1, .stringIndex = 90 } }, // 147 c "A feather you say? One of the queens?"
|
{ .type = type::say, .say = { .characterIndex = 2, .stringIndex = 89 } }, // 147 e "Why you little..."
|
||||||
{ .type = type::say, .say = { .characterIndex = 1, .stringIndex = 91 } }, // 148 c "How on the face of Al Mot might you have aquired such a thing?"
|
{ .type = type::say, .say = { .characterIndex = 1, .stringIndex = 90 } }, // 148 c "A feather you say? One of the queens?"
|
||||||
{ .type = type::say, .say = { .characterIndex = 1, .stringIndex = 92 } }, // 149 c "If it is authentic, that is..."
|
{ .type = type::say, .say = { .characterIndex = 1, .stringIndex = 91 } }, // 149 c "How on the face of Al Mot might you have aquired such a thing?"
|
||||||
{ .type = type::say, .say = { .characterIndex = 2, .stringIndex = 93 } }, // 150 e "Since Alice cannot keep a secret, I shall tell you"
|
{ .type = type::say, .say = { .characterIndex = 1, .stringIndex = 92 } }, // 150 c "If it is authentic, that is..."
|
||||||
{ .type = type::say, .say = { .characterIndex = 2, .stringIndex = 94 } }, // 151 e "Seven moons ago, our town was attacked by three owls and a band of mice from the northern principalities"
|
{ .type = type::say, .say = { .characterIndex = 2, .stringIndex = 93 } }, // 151 e "Since Alice cannot keep a secret, I shall tell you"
|
||||||
{ .type = type::say, .say = { .characterIndex = 2, .stringIndex = 95 } }, // 152 e "Eventually word spread to greater nearby settlements, and so"
|
{ .type = type::say, .say = { .characterIndex = 2, .stringIndex = 94 } }, // 152 e "Seven moons ago, our town was attacked by three owls and a band of mice from the northern principalities"
|
||||||
{ .type = type::say, .say = { .characterIndex = 2, .stringIndex = 96 } }, // 153 e "Messengers from the keep in Musia sent for aid from the Ravens"
|
{ .type = type::say, .say = { .characterIndex = 2, .stringIndex = 95 } }, // 153 e "Eventually word spread to greater nearby settlements, and so"
|
||||||
{ .type = type::say, .say = { .characterIndex = 2, .stringIndex = 97 } }, // 154 e "Four moons ago, the request was answered"
|
{ .type = type::say, .say = { .characterIndex = 2, .stringIndex = 96 } }, // 154 e "Messengers from the keep in Musia sent for aid from the Ravens"
|
||||||
{ .type = type::say, .say = { .characterIndex = 2, .stringIndex = 98 } }, // 155 e "And a small group of mice accompanied by two ravens a fox, and three squirrels set out to the northern principalities"
|
{ .type = type::say, .say = { .characterIndex = 2, .stringIndex = 97 } }, // 155 e "Four moons ago, the request was answered"
|
||||||
{ .type = type::say, .say = { .characterIndex = 2, .stringIndex = 99 } }, // 156 e "Anyways, long story short, we drove those barbaric rats out of their home"
|
{ .type = type::say, .say = { .characterIndex = 2, .stringIndex = 98 } }, // 156 e "And a small group of mice accompanied by two ravens a fox, and three squirrels set out to the northern principalities"
|
||||||
{ .type = type::say, .say = { .characterIndex = 0, .stringIndex = 100 } }, // 157 a "They arent actual rats you know"
|
{ .type = type::say, .say = { .characterIndex = 2, .stringIndex = 99 } }, // 157 e "Anyways, long story short, we drove those barbaric rats out of their home"
|
||||||
{ .type = type::say, .say = { .characterIndex = 2, .stringIndex = 101 } }, // 158 e "Obviously, but you wont catch me speaking kindly of them"
|
{ .type = type::say, .say = { .characterIndex = 0, .stringIndex = 100 } }, // 158 a "They arent actual rats you know"
|
||||||
{ .type = type::say, .say = { .characterIndex = 0, .stringIndex = 102 } }, // 159 a "And you forgot the most important part"
|
{ .type = type::say, .say = { .characterIndex = 2, .stringIndex = 101 } }, // 159 e "Obviously, but you wont catch me speaking kindly of them"
|
||||||
{ .type = type::say, .say = { .characterIndex = 2, .stringIndex = 103 } }, // 160 e "Yah yah, I am getting there"
|
{ .type = type::say, .say = { .characterIndex = 0, .stringIndex = 102 } }, // 160 a "And you forgot the most important part"
|
||||||
{ .type = type::say, .say = { .characterIndex = 2, .stringIndex = 104 } }, // 161 e "So, essentially, my brother is trained in archery, and..."
|
{ .type = type::say, .say = { .characterIndex = 2, .stringIndex = 103 } }, // 161 e "Yah yah, I am getting there"
|
||||||
{ .type = type::say, .say = { .characterIndex = 0, .stringIndex = 105 } }, // 162 a "Speed it up already"
|
{ .type = type::say, .say = { .characterIndex = 2, .stringIndex = 104 } }, // 162 e "So, essentially, my brother is trained in archery, and..."
|
||||||
{ .type = type::say, .say = { .characterIndex = 2, .stringIndex = 106 } }, // 163 e "You tell it then!"
|
{ .type = type::say, .say = { .characterIndex = 0, .stringIndex = 105 } }, // 163 a "Speed it up already"
|
||||||
{ .type = type::say, .say = { .characterIndex = 0, .stringIndex = 107 } }, // 164 a "My cousin found this feather in one of the highest towers of a castle far to the north"
|
{ .type = type::say, .say = { .characterIndex = 2, .stringIndex = 106 } }, // 164 e "You tell it then!"
|
||||||
{ .type = type::say, .say = { .characterIndex = 1, .stringIndex = 108 } }, // 165 c "How do you know it belongs to the queen?"
|
{ .type = type::say, .say = { .characterIndex = 0, .stringIndex = 107 } }, // 165 a "My cousin found this feather in one of the highest towers of a castle far to the north"
|
||||||
{ .type = type::say, .say = { .characterIndex = 2, .stringIndex = 109 } }, // 166 e "It said so itself above the display on the wall"
|
{ .type = type::say, .say = { .characterIndex = 1, .stringIndex = 108 } }, // 166 c "How do you know it belongs to the queen?"
|
||||||
{ .type = type::say, .say = { .characterIndex = 0, .stringIndex = 110 } }, // 167 a "Supposedly, it was in a room filled with treasures!"
|
{ .type = type::say, .say = { .characterIndex = 2, .stringIndex = 109 } }, // 167 e "It said so itself above the display on the wall"
|
||||||
{ .type = type::say, .say = { .characterIndex = 1, .stringIndex = 111 } }, // 168 c "That is very nice and all, but what are the two of you doing out here all alone?"
|
{ .type = type::say, .say = { .characterIndex = 0, .stringIndex = 110 } }, // 168 a "Supposedly, it was in a room filled with treasures!"
|
||||||
{ .type = type::say, .say = { .characterIndex = 1, .stringIndex = 112 } }, // 169 c "Do you expect every bird in Avia to respect your alliance with Castle Alysen?"
|
{ .type = type::say, .say = { .characterIndex = 1, .stringIndex = 111 } }, // 169 c "That is very nice and all, but what are the two of you doing out here all alone?"
|
||||||
{ .type = type::say, .say = { .characterIndex = 2, .stringIndex = 113 } }, // 170 e "What do you mean?"
|
{ .type = type::say, .say = { .characterIndex = 1, .stringIndex = 112 } }, // 170 c "Do you expect every bird in Avia to respect your alliance with Castle Alysen?"
|
||||||
{ .type = type::say, .say = { .characterIndex = 1, .stringIndex = 114 } }, // 171 c "I mean, the two of you probably look like walking dinner to most creatures"
|
{ .type = type::say, .say = { .characterIndex = 2, .stringIndex = 113 } }, // 171 e "What do you mean?"
|
||||||
{ .type = type::say, .say = { .characterIndex = 0, .stringIndex = 115 } }, // 172 a "I could go for some dinner..."
|
{ .type = type::say, .say = { .characterIndex = 1, .stringIndex = 114 } }, // 172 c "I mean, the two of you probably look like walking dinner to most creatures"
|
||||||
{ .type = type::say, .say = { .characterIndex = 2, .stringIndex = 116 } }, // 173 e "Anyways..."
|
{ .type = type::say, .say = { .characterIndex = 0, .stringIndex = 115 } }, // 173 a "I could go for some dinner..."
|
||||||
{ .type = type::say, .say = { .characterIndex = 2, .stringIndex = 117 } }, // 174 e "To answer your question, upon returning to the village, the feather was taken from my brother by the needle guild"
|
{ .type = type::say, .say = { .characterIndex = 2, .stringIndex = 116 } }, // 174 e "Anyways..."
|
||||||
{ .type = type::say, .say = { .characterIndex = 2, .stringIndex = 118 } }, // 175 e "So... Yesterday, after sundown"
|
{ .type = type::say, .say = { .characterIndex = 2, .stringIndex = 117 } }, // 175 e "To answer your question, upon returning to the village, the feather was taken from my brother by the needle guild"
|
||||||
{ .type = type::say, .say = { .characterIndex = 2, .stringIndex = 119 } }, // 176 e "We stole the feather from the guild hall before vanishing into the night"
|
{ .type = type::say, .say = { .characterIndex = 2, .stringIndex = 118 } }, // 176 e "So... Yesterday, after sundown"
|
||||||
{ .type = type::say, .say = { .characterIndex = 2, .stringIndex = 120 } }, // 177 e "Can you imagine the look on their stupid faces, when they woke up, and not only is the feather missing"
|
{ .type = type::say, .say = { .characterIndex = 2, .stringIndex = 119 } }, // 177 e "We stole the feather from the guild hall before vanishing into the night"
|
||||||
{ .type = type::say, .say = { .characterIndex = 2, .stringIndex = 121 } }, // 178 e "But so are we!"
|
{ .type = type::say, .say = { .characterIndex = 2, .stringIndex = 120 } }, // 178 e "Can you imagine the look on their stupid faces, when they woke up, and not only is the feather missing"
|
||||||
{ .type = type::say, .say = { .characterIndex = 0, .stringIndex = 122 } }, // 179 a "Hahahaha"
|
{ .type = type::say, .say = { .characterIndex = 2, .stringIndex = 121 } }, // 179 e "But so are we!"
|
||||||
{ .type = type::say, .say = { .characterIndex = 1, .stringIndex = 123 } }, // 180 c "Are the two of you mad?"
|
{ .type = type::say, .say = { .characterIndex = 0, .stringIndex = 122 } }, // 180 a "Hahahaha"
|
||||||
{ .type = type::say, .say = { .characterIndex = 1, .stringIndex = 124 } }, // 181 c "I assume you are attempting to return the Queens feather?"
|
{ .type = type::say, .say = { .characterIndex = 1, .stringIndex = 123 } }, // 181 c "Are the two of you mad?"
|
||||||
{ .type = type::say, .say = { .characterIndex = 0, .stringIndex = 125 } }, // 182 a "Yes, we intend to deliver the feather to its rightful owner"
|
{ .type = type::say, .say = { .characterIndex = 1, .stringIndex = 124 } }, // 182 c "I assume you are attempting to return the Queens feather?"
|
||||||
{ .type = type::say, .say = { .characterIndex = 1, .stringIndex = 126 } }, // 183 c "Absolute madness!"
|
{ .type = type::say, .say = { .characterIndex = 0, .stringIndex = 125 } }, // 183 a "Yes, we intend to deliver the feather to its rightful owner"
|
||||||
{ .type = type::say, .say = { .characterIndex = 3, .stringIndex = 31 } }, // 184 mg "..."
|
{ .type = type::say, .say = { .characterIndex = 1, .stringIndex = 126 } }, // 184 c "Absolute madness!"
|
||||||
{ .type = type::say, .say = { .characterIndex = 1, .stringIndex = 127 } }, // 185 c "I will follow the two of you"
|
{ .type = type::say, .say = { .characterIndex = 3, .stringIndex = 31 } }, // 185 mg "..."
|
||||||
{ .type = type::say, .say = { .characterIndex = 1, .stringIndex = 128 } }, // 186 c "To keep you safe, that is"
|
{ .type = type::say, .say = { .characterIndex = 1, .stringIndex = 127 } }, // 186 c "I will follow the two of you"
|
||||||
{ .type = type::say, .say = { .characterIndex = 0, .stringIndex = 129 } }, // 187 a "Alright!"
|
{ .type = type::say, .say = { .characterIndex = 1, .stringIndex = 128 } }, // 187 c "To keep you safe, that is"
|
||||||
{ .type = type::say, .say = { .characterIndex = 2, .stringIndex = 130 } }, // 188 e "Ha ha... Okay..."
|
{ .type = type::say, .say = { .characterIndex = 0, .stringIndex = 129 } }, // 188 a "Alright!"
|
||||||
{ .type = type::say, .say = { .characterIndex = 1, .stringIndex = 131 } }, // 189 c "Great! Follow me, I know a shortcut! :3"
|
{ .type = type::say, .say = { .characterIndex = 2, .stringIndex = 130 } }, // 189 e "Ha ha... Okay..."
|
||||||
{ .type = type::hide, .hide = { .imageIndex = 5 } }, // 190 cat
|
{ .type = type::say, .say = { .characterIndex = 1, .stringIndex = 131 } }, // 190 c "Great! Follow me, I know a shortcut! :3"
|
||||||
{ .type = type::say, .say = { .characterIndex = 0, .stringIndex = 132 } }, // 191 a "Sounds good!"
|
{ .type = type::hide, .hide = { .imageIndex = 5 } }, // 191 cat
|
||||||
{ .type = type::hide, .hide = { .imageIndex = 8 } }, // 192 al
|
{ .type = type::say, .say = { .characterIndex = 0, .stringIndex = 132 } }, // 192 a "Sounds good!"
|
||||||
{ .type = type::stop, .stop = { /* FIXME channel */ } }, // 193
|
{ .type = type::hide, .hide = { .imageIndex = 8 } }, // 193 al
|
||||||
{ .type = type::say, .say = { .characterIndex = 2, .stringIndex = 133 } }, // 194 e "Oh dear!"
|
{ .type = type::stop, .stop = { .audioIndex = 3, .fadeout = 2.0 } }, // 194 PhrygianButterflies
|
||||||
{ .type = type::hide, .hide = { .imageIndex = 7 } }, // 195 ei
|
{ .type = type::say, .say = { .characterIndex = 2, .stringIndex = 133 } }, // 195 e "Oh dear!"
|
||||||
{ .type = type::scene_color, .scene_color = { .color = 0xffffff } }, // 196 bgwhite
|
{ .type = type::hide, .hide = { .imageIndex = 7 } }, // 196 ei
|
||||||
{ .type = type::play, .play = { .audioIndex = 0 } }, // 197 sfx/Chime.ogg
|
{ .type = type::scene_color, .scene_color = { .color = 0xffffff } }, // 197 bgwhite
|
||||||
{ .type = type::dissolve, .dissolve = { .duration = 2.0 } }, // 198
|
{ .type = type::play, .play = { .audioIndex = 0 } }, // 198 sfx/Chime.ogg
|
||||||
{ .type = type::say, .say = { .characterIndex = 4, .stringIndex = 134 } }, // 199 n "And so the mice girls follow the noble cat further towards their destination"
|
{ .type = type::dissolve, .dissolve = { .duration = 2.0 } }, // 199
|
||||||
{ .type = type::scene, .scene = { .imageIndex = 4 } }, // 200 bgwheatfield1
|
{ .type = type::say, .say = { .characterIndex = 4, .stringIndex = 134 } }, // 200 n "And so the mice girls follow the noble cat further towards their destination"
|
||||||
{ .type = type::play, .play = { .audioIndex = 7 } }, // 201 music/WheatFields.ogg
|
{ .type = type::scene, .scene = { .imageIndex = 4 } }, // 201 bgwheatfield1
|
||||||
{ .type = type::show, .show = { .imageIndex = 5, .transformIndex = transform::right } }, // 202 cat
|
{ .type = type::play, .play = { .audioIndex = 7 } }, // 202 music/WheatFields.ogg
|
||||||
{ .type = type::dissolve, .dissolve = { .duration = 1.3 } }, // 203
|
{ .type = type::show, .show = { .imageIndex = 5, .transformIndex = transform::right } }, // 203 cat
|
||||||
{ .type = type::say, .say = { .characterIndex = 1, .stringIndex = 135 } }, // 204 c "Nya"
|
{ .type = type::dissolve, .dissolve = { .duration = 1.3 } }, // 204
|
||||||
{ .type = type::show, .show = { .imageIndex = 8, .transformIndex = transform::left } }, // 205 al
|
{ .type = type::say, .say = { .characterIndex = 1, .stringIndex = 135 } }, // 205 c "Nya"
|
||||||
{ .type = type::say, .say = { .characterIndex = 0, .stringIndex = 136 } }, // 206 a "Look, your right, the castle is just up ahead!"
|
{ .type = type::show, .show = { .imageIndex = 8, .transformIndex = transform::left } }, // 206 al
|
||||||
{ .type = type::show, .show = { .imageIndex = 7, .transformIndex = transform::centerleft } }, // 207 ei
|
{ .type = type::say, .say = { .characterIndex = 0, .stringIndex = 136 } }, // 207 a "Look, your right, the castle is just up ahead!"
|
||||||
{ .type = type::say, .say = { .characterIndex = 2, .stringIndex = 137 } }, // 208 e "Wait up"
|
{ .type = type::show, .show = { .imageIndex = 7, .transformIndex = transform::centerleft } }, // 208 ei
|
||||||
{ .type = type::say, .say = { .characterIndex = 1, .stringIndex = 138 } }, // 209 c "I told you I knew a shortcut!"
|
{ .type = type::say, .say = { .characterIndex = 2, .stringIndex = 137 } }, // 209 e "Wait up"
|
||||||
{ .type = type::say, .say = { .characterIndex = 1, .stringIndex = 139 } }, // 210 c "Most people take the long way around"
|
{ .type = type::say, .say = { .characterIndex = 1, .stringIndex = 138 } }, // 210 c "I told you I knew a shortcut!"
|
||||||
{ .type = type::say, .say = { .characterIndex = 2, .stringIndex = 140 } }, // 211 e "Yah because these are royal wheatfields!"
|
{ .type = type::say, .say = { .characterIndex = 1, .stringIndex = 139 } }, // 211 c "Most people take the long way around"
|
||||||
{ .type = type::say, .say = { .characterIndex = 0, .stringIndex = 141 } }, // 212 a "Who cares?"
|
{ .type = type::say, .say = { .characterIndex = 2, .stringIndex = 140 } }, // 212 e "Yah because these are royal wheatfields!"
|
||||||
{ .type = type::say, .say = { .characterIndex = 2, .stringIndex = 142 } }, // 213 e "Are you trying to get us killed?"
|
{ .type = type::say, .say = { .characterIndex = 0, .stringIndex = 141 } }, // 213 a "Who cares?"
|
||||||
{ .type = type::say, .say = { .characterIndex = 2, .stringIndex = 143 } }, // 214 e "Its trespassing on royal land!"
|
{ .type = type::say, .say = { .characterIndex = 2, .stringIndex = 142 } }, // 214 e "Are you trying to get us killed?"
|
||||||
{ .type = type::say, .say = { .characterIndex = 1, .stringIndex = 144 } }, // 215 c "Calm down, I have done this a million times"
|
{ .type = type::say, .say = { .characterIndex = 2, .stringIndex = 143 } }, // 215 e "Its trespassing on royal land!"
|
||||||
{ .type = type::say, .say = { .characterIndex = 2, .stringIndex = 145 } }, // 216 e "That doesnt make me calm!"
|
{ .type = type::say, .say = { .characterIndex = 1, .stringIndex = 144 } }, // 216 c "Calm down, I have done this a million times"
|
||||||
{ .type = type::say, .say = { .characterIndex = 1, .stringIndex = 146 } }, // 217 c "How can the rolling fields of wheat not calm your spirit?"
|
{ .type = type::say, .say = { .characterIndex = 2, .stringIndex = 145 } }, // 217 e "That doesnt make me calm!"
|
||||||
{ .type = type::say, .say = { .characterIndex = 1, .stringIndex = 147 } }, // 218 c "You little mice truly are mad!"
|
{ .type = type::say, .say = { .characterIndex = 1, .stringIndex = 146 } }, // 218 c "How can the rolling fields of wheat not calm your spirit?"
|
||||||
{ .type = type::say, .say = { .characterIndex = 0, .stringIndex = 148 } }, // 219 a "I like the wheat!"
|
{ .type = type::say, .say = { .characterIndex = 1, .stringIndex = 147 } }, // 219 c "You little mice truly are mad!"
|
||||||
{ .type = type::say, .say = { .characterIndex = 2, .stringIndex = 149 } }, // 220 e "Shut up!"
|
{ .type = type::say, .say = { .characterIndex = 0, .stringIndex = 148 } }, // 220 a "I like the wheat!"
|
||||||
{ .type = type::say, .say = { .characterIndex = 1, .stringIndex = 150 } }, // 221 c "Sounds like someone needs a nap!"
|
{ .type = type::say, .say = { .characterIndex = 2, .stringIndex = 149 } }, // 221 e "Shut up!"
|
||||||
{ .type = type::say, .say = { .characterIndex = 2, .stringIndex = 151 } }, // 222 e "Why? because I'm not insane like you?"
|
{ .type = type::say, .say = { .characterIndex = 1, .stringIndex = 150 } }, // 222 c "Sounds like someone needs a nap!"
|
||||||
{ .type = type::say, .say = { .characterIndex = 1, .stringIndex = 152 } }, // 223 c "Yah, your so sane, that you decided to steal from your town and then run off alone to the country of birds"
|
{ .type = type::say, .say = { .characterIndex = 2, .stringIndex = 151 } }, // 223 e "Why? because I'm not insane like you?"
|
||||||
{ .type = type::say, .say = { .characterIndex = 1, .stringIndex = 153 } }, // 224 c "The power of friendship wont protect the two of you from becoming dinner"
|
{ .type = type::say, .say = { .characterIndex = 1, .stringIndex = 152 } }, // 224 c "Yah, your so sane, that you decided to steal from your town and then run off alone to the country of birds"
|
||||||
{ .type = type::say, .say = { .characterIndex = 1, .stringIndex = 154 } }, // 225 c "And that, is why I feel obligated to accompany you!"
|
{ .type = type::say, .say = { .characterIndex = 1, .stringIndex = 153 } }, // 225 c "The power of friendship wont protect the two of you from becoming dinner"
|
||||||
{ .type = type::say, .say = { .characterIndex = 2, .stringIndex = 155 } }, // 226 e "Hey, we have a good reason!"
|
{ .type = type::say, .say = { .characterIndex = 1, .stringIndex = 154 } }, // 226 c "And that, is why I feel obligated to accompany you!"
|
||||||
{ .type = type::say, .say = { .characterIndex = 1, .stringIndex = 156 } }, // 227 c "And what might that be?"
|
{ .type = type::say, .say = { .characterIndex = 2, .stringIndex = 155 } }, // 227 e "Hey, we have a good reason!"
|
||||||
{ .type = type::say, .say = { .characterIndex = 2, .stringIndex = 157 } }, // 228 e "My brother found the feather, not the town guild, its a matter of family pride!"
|
{ .type = type::say, .say = { .characterIndex = 1, .stringIndex = 156 } }, // 228 c "And what might that be?"
|
||||||
{ .type = type::say, .say = { .characterIndex = 1, .stringIndex = 158 } }, // 229 c "Pride has touched the chosen meouse"
|
{ .type = type::say, .say = { .characterIndex = 2, .stringIndex = 157 } }, // 229 e "My brother found the feather, not the town guild, its a matter of family pride!"
|
||||||
{ .type = type::say, .say = { .characterIndex = 1, .stringIndex = 159 } }, // 230 c "Flies she towards the Castle"
|
{ .type = type::say, .say = { .characterIndex = 1, .stringIndex = 158 } }, // 230 c "Pride has touched the chosen meouse"
|
||||||
{ .type = type::say, .say = { .characterIndex = 1, .stringIndex = 160 } }, // 231 c "But her ambition burns far too bright, and silly myice dont have any wings to myelt"
|
{ .type = type::say, .say = { .characterIndex = 1, .stringIndex = 159 } }, // 231 c "Flies she towards the Castle"
|
||||||
{ .type = type::say, .say = { .characterIndex = 3, .stringIndex = 161 } }, // 232 mg "What?"
|
{ .type = type::say, .say = { .characterIndex = 1, .stringIndex = 160 } }, // 232 c "But her ambition burns far too bright, and silly myice dont have any wings to myelt"
|
||||||
{ .type = type::say, .say = { .characterIndex = 1, .stringIndex = 162 } }, // 233 c "Nyanyanya"
|
{ .type = type::say, .say = { .characterIndex = 3, .stringIndex = 161 } }, // 233 mg "What?"
|
||||||
{ .type = type::say, .say = { .characterIndex = 1, .stringIndex = 163 } }, // 234 c "Nyevermind"
|
{ .type = type::say, .say = { .characterIndex = 1, .stringIndex = 162 } }, // 234 c "Nyanyanya"
|
||||||
{ .type = type::say, .say = { .characterIndex = 1, .stringIndex = 164 } }, // 235 c "Sing me a song little minstrels!"
|
{ .type = type::say, .say = { .characterIndex = 1, .stringIndex = 163 } }, // 235 c "Nyevermind"
|
||||||
{ .type = type::say, .say = { .characterIndex = 1, .stringIndex = 165 } }, // 236 c "Very Nyice!"
|
{ .type = type::say, .say = { .characterIndex = 1, .stringIndex = 164 } }, // 236 c "Sing me a song little minstrels!"
|
||||||
{ .type = type::say, .say = { .characterIndex = 1, .stringIndex = 166 } }, // 237 c "Now tell me little minstrels, what are your names?"
|
{ .type = type::say, .say = { .characterIndex = 1, .stringIndex = 165 } }, // 237 c "Very Nyice!"
|
||||||
{ .type = type::say, .say = { .characterIndex = 0, .stringIndex = 167 } }, // 238 a "My name is Alice"
|
{ .type = type::say, .say = { .characterIndex = 1, .stringIndex = 166 } }, // 238 c "Now tell me little minstrels, what are your names?"
|
||||||
{ .type = type::say, .say = { .characterIndex = 2, .stringIndex = 168 } }, // 239 e "And my name is Eily"
|
{ .type = type::say, .say = { .characterIndex = 0, .stringIndex = 167 } }, // 239 a "My name is Alice"
|
||||||
{ .type = type::say, .say = { .characterIndex = 2, .stringIndex = 169 } }, // 240 e "What is your name?"
|
{ .type = type::say, .say = { .characterIndex = 2, .stringIndex = 168 } }, // 240 e "And my name is Eily"
|
||||||
{ .type = type::say, .say = { .characterIndex = 5, .stringIndex = 170 } }, // 241 l "My name is Leona!"
|
{ .type = type::say, .say = { .characterIndex = 2, .stringIndex = 169 } }, // 241 e "What is your name?"
|
||||||
{ .type = type::scene_color, .scene_color = { .color = 0xffffff } }, // 242 bgwhite
|
{ .type = type::say, .say = { .characterIndex = 5, .stringIndex = 170 } }, // 242 l "My name is Leona!"
|
||||||
{ .type = type::dissolve, .dissolve = { .duration = 3.0 } }, // 243
|
{ .type = type::scene_color, .scene_color = { .color = 0xffffff } }, // 243 bgwhite
|
||||||
{ .type = type::say, .say = { .characterIndex = 4, .stringIndex = 171 } }, // 244 n "And so, the odd trio walked through the wheatfields and towards the castle walls"
|
{ .type = type::dissolve, .dissolve = { .duration = 3.0 } }, // 244
|
||||||
{ .type = type::say, .say = { .characterIndex = 4, .stringIndex = 172 } }, // 245 n "Upon approaching the castle walls"
|
{ .type = type::say, .say = { .characterIndex = 4, .stringIndex = 171 } }, // 245 n "And so, the odd trio walked through the wheatfields and towards the castle walls"
|
||||||
{ .type = type::_return }, // 246
|
{ .type = type::say, .say = { .characterIndex = 4, .stringIndex = 172 } }, // 246 n "Upon approaching the castle walls"
|
||||||
|
{ .type = type::_return }, // 247
|
||||||
};
|
};
|
||||||
|
|
||||||
const int statements_length = (sizeof (statements)) / (sizeof (statements[0]));
|
const int statements_length = (sizeof (statements)) / (sizeof (statements[0]));
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user