diff --git a/Makefile b/Makefile index 1024bb3..13b09e5 100644 --- a/Makefile +++ b/Makefile @@ -110,6 +110,12 @@ all: main %.pcm: %.wav ffmpeg -loglevel quiet -y -i $< -c:a pcm_s16le -ar 48000 -ac 2 -f s16le $@ +%.pcm: %.ogg + ffmpeg -loglevel quiet -y -i $< -c:a pcm_s16le -ar 48000 -ac 2 -f s16le $@ + +%.pcm: %.mp3 + ffmpeg -loglevel quiet -y -i $< -c:a pcm_s16le -ar 48000 -ac 2 -f s16le $@ + %.opus.bin: %.pcm ./tools/opus_encode $< $@ diff --git a/audio/MistAmbience.wav b/audio/music/MistAmbience.wav similarity index 100% rename from audio/MistAmbience.wav rename to audio/music/MistAmbience.wav diff --git a/audio/PhrygianButterflies.opus.bin b/audio/music/PhrygianButterflies.opus.bin similarity index 100% rename from audio/PhrygianButterflies.opus.bin rename to audio/music/PhrygianButterflies.opus.bin diff --git a/audio/PhrygianButterflies.wav b/audio/music/PhrygianButterflies.wav similarity index 100% rename from audio/PhrygianButterflies.wav rename to audio/music/PhrygianButterflies.wav diff --git a/audio/music/Poem1.ogg b/audio/music/Poem1.ogg new file mode 100644 index 0000000..30602c5 Binary files /dev/null and b/audio/music/Poem1.ogg differ diff --git a/audio/music/Poem1.opus.bin b/audio/music/Poem1.opus.bin new file mode 100644 index 0000000..5408328 Binary files /dev/null and b/audio/music/Poem1.opus.bin differ diff --git a/audio/ScaredMice.opus.bin b/audio/music/ScaredMice.opus.bin similarity index 100% rename from audio/ScaredMice.opus.bin rename to audio/music/ScaredMice.opus.bin diff --git a/audio/ScaredMice.wav b/audio/music/ScaredMice.wav similarity index 100% rename from audio/ScaredMice.wav rename to audio/music/ScaredMice.wav diff --git a/audio/music/TinyForestMinstrels.opus.bin b/audio/music/TinyForestMinstrels.opus.bin new file mode 100644 index 0000000..5fdc628 Binary files /dev/null and b/audio/music/TinyForestMinstrels.opus.bin differ diff --git a/audio/TinyForestMinstrels.wav b/audio/music/TinyForestMinstrels.wav similarity index 100% rename from audio/TinyForestMinstrels.wav rename to audio/music/TinyForestMinstrels.wav diff --git a/audio/music/WheatFields.opus.bin b/audio/music/WheatFields.opus.bin new file mode 100644 index 0000000..d3932b2 Binary files /dev/null and b/audio/music/WheatFields.opus.bin differ diff --git a/audio/WheatFields.wav b/audio/music/WheatFields.wav similarity index 100% rename from audio/WheatFields.wav rename to audio/music/WheatFields.wav diff --git a/audio/placeholdermeow.mp3 b/audio/placeholdermeow.mp3 new file mode 100644 index 0000000..f488fdb Binary files /dev/null and b/audio/placeholdermeow.mp3 differ diff --git a/audio/placeholdermeow.opus.bin b/audio/placeholdermeow.opus.bin new file mode 100644 index 0000000..4d2602d Binary files /dev/null and b/audio/placeholdermeow.opus.bin differ diff --git a/audio/sfx/Chime.ogg b/audio/sfx/Chime.ogg new file mode 100644 index 0000000..7324bf5 Binary files /dev/null and b/audio/sfx/Chime.ogg differ diff --git a/audio/sfx/Chime.opus.bin b/audio/sfx/Chime.opus.bin new file mode 100644 index 0000000..b5b1b35 Binary files /dev/null and b/audio/sfx/Chime.opus.bin differ diff --git a/audio/sfx/MistAmbience.ogg b/audio/sfx/MistAmbience.ogg new file mode 100644 index 0000000..8dcdfbd Binary files /dev/null and b/audio/sfx/MistAmbience.ogg differ diff --git a/audio/sfx/MistAmbience.opus.bin b/audio/sfx/MistAmbience.opus.bin new file mode 100644 index 0000000..9e0538f Binary files /dev/null and b/audio/sfx/MistAmbience.opus.bin differ diff --git a/data/renpy/script.rpy b/data/renpy/script.rpy index 2efbea0..d578a77 100644 --- a/data/renpy/script.rpy +++ b/data/renpy/script.rpy @@ -127,7 +127,7 @@ label start: with Dissolve(1.0) - voice "n5test.ogg" + #voice "n5test.ogg" n "As the minstrel mice girls continue along the path, the forest opens up into a beautiful field of flowers" play PhrygianButterflies "music/PhrygianButterflies.ogg" diff --git a/filenames.txt b/filenames.txt index 3bb0472..ed46b01 100644 --- a/filenames.txt +++ b/filenames.txt @@ -12,4 +12,11 @@ data/renpy/images/ch/catw.dds data/renpy/images/ch/Eily.dds data/renpy/images/ch/Alice.dds -audio/PhrygianButterflies.opus.bin +audio/sfx/Chime.opus.bin +audio/sfx/MistAmbience.opus.bin +audio/music/TinyForestMinstrels.opus.bin +audio/music/PhrygianButterflies.opus.bin +audio/music/Poem1.opus.bin +audio/placeholdermeow.opus.bin +audio/music/ScaredMice.opus.bin +audio/music/WheatFields.opus.bin diff --git a/include/audio.h b/include/audio.h index 9a79fbd..d625781 100644 --- a/include/audio.h +++ b/include/audio.h @@ -1,7 +1,9 @@ #pragma once +#include "renpy/language.h" + namespace audio { void init(); - void load(); + void load(renpy::language::audio const * const audio, int count); void update(); } diff --git a/include/renpy/language.h b/include/renpy/language.h index 184a28e..d286529 100644 --- a/include/renpy/language.h +++ b/include/renpy/language.h @@ -25,6 +25,8 @@ namespace renpy::language { struct audio { char const * const path; + char const * const name; + uint32_t loop; }; struct image { diff --git a/renpy-parser/parse.py b/renpy-parser/parse.py index 5b9c728..b8df436 100644 --- a/renpy-parser/parse.py +++ b/renpy-parser/parse.py @@ -56,7 +56,6 @@ class Play: channel: lex.Token path: lex.Token fadeout: lex.Token - noloop: bool __repr__ = lexeme_repr @@ -263,16 +262,15 @@ def parse_play(tokens, index): if fadeout.type != TT.NUMBER: raise ParseException("expected number", fadeout) index += 2 - noloop = False + #noloop = False if token.type == TT.NOLOOP: - noloop = True + #noloop = True index += 1 play = Play( channel = channel, path = path, fadeout = fadeout, - noloop = noloop, ) return index, play diff --git a/renpy-parser/transform.py b/renpy-parser/transform.py index 8f4bfa3..e7ccddd 100644 --- a/renpy-parser/transform.py +++ b/renpy-parser/transform.py @@ -51,6 +51,14 @@ simple_statement_types = { parse.Hide, } +loops = { + "ScaredMice": 8.0, + "PhrygianButterflies": 40.125, + "MistAmbience": 22.0, + "TinyForestMinstrels": 44.0, + "WheatFields": 34.0, +} + def pass1(state, ast): if type(ast) is parse.Image: key = lhs_key(ast.name) @@ -78,7 +86,8 @@ def pass1(state, ast): elif type(ast) in {parse.Play, parse.Voice}: if ast.path.lexeme not in state.audio_lookup: index = len(state.audio_lookup) - state.audio_lookup[ast.path.lexeme] = index + channel = ast.channel.lexeme if type(ast) is parse.Play else None + state.audio_lookup[ast.path.lexeme] = (index, channel) elif type(ast) is parse.Say: if ast.text.lexeme not in state.string_lookup: index = len(state.string_lookup) @@ -134,8 +143,9 @@ def parse_color(b): def pass2_statement(state, pc, statement): if type(statement) is parse.Play: comment = statement.path.lexeme.decode('utf-8') - audio_index = state.audio_lookup[statement.path.lexeme] - yield f"{{ .type = type::play, .play = {{ .audioIndex = {audio_index}, /* FIXME channel */ }} }}, // {pc} {comment}" + audio_index, channel = state.audio_lookup[statement.path.lexeme] + assert channel is not None + yield f"{{ .type = type::play, .play = {{ .audioIndex = {audio_index} }} }}, // {pc} {comment}" elif type(statement) is parse.Scene: key = lhs_key(statement.name) if key in state.images_lookup: @@ -156,7 +166,8 @@ def pass2_statement(state, pc, statement): assert False, (pc, statement) elif type(statement) is parse.Voice: comment = statement.path.lexeme.decode('utf-8') - audio_index = state.audio_lookup[statement.path.lexeme] + audio_index, channel = state.audio_lookup[statement.path.lexeme] + assert channel is None yield f"{{ .type = type::voice, .voice = {{ .audioIndex = {audio_index} }} }}, // {pc} {comment}" elif type(statement) is parse.Say: key = lhs_key(statement.speaker) @@ -230,7 +241,7 @@ def pass2_characters(state): def pass2_audio(state): yield "const language::audio audio[] = {" - for audio, i in sorted(state.audio_lookup.items(), key=lambda kv: kv[1]): + for audio, (i, channel) in sorted(state.audio_lookup.items(), key=lambda kv: kv[1][0]): orig_path = audio.decode('utf-8') path = orig_path if path.endswith(".mp3"): @@ -239,7 +250,12 @@ def pass2_audio(state): path = path.removesuffix(".ogg") else: assert False, path - yield f"{{ .path = \"{path}.opus\" }}, // {i} {orig_path}" + name = audio + channel_name = channel.decode('utf-8') if channel is not None else None + name = f"\"{channel_name}\"" if channel is not None else "nullptr" + loop = loops[channel_name] if channel_name in loops else 0 + assert loop < 20_000, loop + yield f"{{ .path = \"audio/{path}.opus.bin\", .name = {name}, .loop = {int(loop * 48000)} }}, // {i} {orig_path}" yield "};" yield "const int audio_length = (sizeof (audio)) / (sizeof (audio[0]));" diff --git a/src/audio.cpp b/src/audio.cpp index b4081c7..326d09e 100644 --- a/src/audio.cpp +++ b/src/audio.cpp @@ -9,6 +9,7 @@ #include "audio.h" #include "new.h" #include "minmax.h" +#include "renpy/language.h" namespace audio { @@ -27,13 +28,8 @@ namespace audio { OpusDecoder * opus_decoder; - struct AudioFile { - char const * const path; - uint32_t loop_end; - }; - struct AudioBuffer { - AudioFile * audio_file; + renpy::language::audio const * audio; int16_t * buf; uint32_t sample_count; }; @@ -44,22 +40,11 @@ namespace audio { uint32_t tail_index; }; - consteval uint32_t time_to_samples(double m, double s) - { - return (m * 60.0 + s) * sample_rate; - } - - AudioFile audio_files[] = { - { - .path = "audio/PhrygianButterflies.opus.bin", - .loop_end = time_to_samples(0, 40.125), - }, - }; - constexpr int audio_files_count = (sizeof (audio_files)) / (sizeof (audio_files[0])); - AudioBuffer audio_buffers[audio_files_count]; + AudioBuffer * audio_buffers; constexpr int max_audio_instances = 16; AudioInstance audio_instances[max_audio_instances]; + int instance_count; void init() { @@ -76,6 +61,8 @@ namespace audio { fprintf(stderr, "opus_decoder_create: %s\n", opus_strerror(err)); assert(!"opus_decoder_create"); } + + instance_count = 0; } void decode(char const * const filename, AudioBuffer * audio_buffer) @@ -131,14 +118,15 @@ namespace audio { assert(audio_buffer->sample_count / 2); } - void load() + void load(renpy::language::audio const * const audio, int count) { - for (int i = 0; i < audio_files_count; i++) { - audio_buffers[i].audio_file = &audio_files[i]; - decode(audio_files[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; + audio_buffers = NewM(count); + for (int i = 0; i < count; i++) { + audio_buffers[i].audio = &audio[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; } } @@ -157,6 +145,7 @@ namespace audio { int16_t mix_buffer[half_period_samples * channels]; memset(mix_buffer, 0, (sizeof (mix_buffer))); + /* AudioInstance & instance = audio_instances[0]; int16_t const * const buf = instance.audio_buffer->buf; uint32_t const sample_count = instance.audio_buffer->sample_count; @@ -188,5 +177,6 @@ namespace audio { } SDL_PutAudioStreamData(audio_stream, (void *)mix_buffer, half_period_size); + */ } } diff --git a/src/main.cpp b/src/main.cpp index c5c1d61..a4f8293 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -24,6 +24,7 @@ #include "renpy/vulkan.h" #include "renpy/interpreter.h" #include "renpy/interact.h" +#include "renpy/script.h" #include "scenes/shadow_test/shadow_test.h" #include "scenes/eidelwind/eidelwind.h" @@ -772,7 +773,7 @@ int main() //collada_state.update(0); audio::init(); - audio::load(); + audio::load(renpy::script::audio, renpy::script::audio_length); while (quit == false) { audio::update(); diff --git a/src/renpy/script.cpp b/src/renpy/script.cpp index a93ac6f..7644e86 100644 --- a/src/renpy/script.cpp +++ b/src/renpy/script.cpp @@ -194,15 +194,14 @@ const language::character characters[] = { const int characters_length = (sizeof (characters)) / (sizeof (characters[0])); const language::audio audio[] = { - { .path = "sfx/Chime.opus" }, // 0 sfx/Chime.ogg - { .path = "sfx/MistAmbience.opus" }, // 1 sfx/MistAmbience.ogg - { .path = "music/TinyForestMinstrels.opus" }, // 2 music/TinyForestMinstrels.ogg - { .path = "n5test.opus" }, // 3 n5test.ogg - { .path = "music/PhrygianButterflies.opus" }, // 4 music/PhrygianButterflies.ogg - { .path = "music/Poem1.opus" }, // 5 music/Poem1.ogg - { .path = "placeholdermeow.opus" }, // 6 placeholdermeow.mp3 - { .path = "music/ScaredMice.opus" }, // 7 music/ScaredMice.ogg - { .path = "music/WheatFields.opus" }, // 8 music/WheatFields.ogg + { .path = "audio/sfx/Chime.opus.bin", .name = "sound", .loop = 0 }, // 0 sfx/Chime.ogg + { .path = "audio/sfx/MistAmbience.opus.bin", .name = "MistAmbience", .loop = 1056000 }, // 1 sfx/MistAmbience.ogg + { .path = "audio/music/TinyForestMinstrels.opus.bin", .name = "TinyForestMinstrels", .loop = 2112000 }, // 2 music/TinyForestMinstrels.ogg + { .path = "audio/music/PhrygianButterflies.opus.bin", .name = "PhrygianButterflies", .loop = 1926000 }, // 3 music/PhrygianButterflies.ogg + { .path = "audio/music/Poem1.opus.bin", .name = "music", .loop = 0 }, // 4 music/Poem1.ogg + { .path = "audio/placeholdermeow.opus.bin", .name = nullptr, .loop = 0 }, // 5 placeholdermeow.mp3 + { .path = "audio/music/ScaredMice.opus.bin", .name = "ScaredMice", .loop = 384000 }, // 6 music/ScaredMice.ogg + { .path = "audio/music/WheatFields.opus.bin", .name = "WheatFields", .loop = 1632000 }, // 7 music/WheatFields.ogg }; const int audio_length = (sizeof (audio)) / (sizeof (audio[0])); @@ -224,23 +223,23 @@ const int images_length = (sizeof (images)) / (sizeof (images[0])); const language::option options[] = { { .string = "Complain", .statementIndex = 18 }, // 0 { .string = "Rationalize", .statementIndex = 26 }, // 1 - { .string = "Good idea", .statementIndex = 54 }, // 2 - { .string = "I am too tired", .statementIndex = 61 }, // 3 - { .string = "Beg for mercy", .statementIndex = 78 }, // 4 - { .string = "Run", .statementIndex = 80 }, // 5 + { .string = "Good idea", .statementIndex = 53 }, // 2 + { .string = "I am too tired", .statementIndex = 60 }, // 3 + { .string = "Beg for mercy", .statementIndex = 77 }, // 4 + { .string = "Run", .statementIndex = 79 }, // 5 }; const int options_length = (sizeof (options)) / (sizeof (options[0])); const language::statement statements[] = { - { .type = type::play, .play = { .audioIndex = 0, /* FIXME channel */ } }, // 0 sfx/Chime.ogg - { .type = type::play, .play = { .audioIndex = 1, /* FIXME channel */ } }, // 1 sfx/MistAmbience.ogg + { .type = type::play, .play = { .audioIndex = 0 } }, // 0 sfx/Chime.ogg + { .type = type::play, .play = { .audioIndex = 1 } }, // 1 sfx/MistAmbience.ogg { .type = type::scene_color, .scene_color = { .color = 0xffffff } }, // 2 bgwhite { .type = type::dissolve, .dissolve = { .duration = 3.0 } }, // 3 { .type = type::say, .say = { .characterIndex = 4, .stringIndex = 0 } }, // 4 n "Far over the mountains of Almystice" { .type = type::say, .say = { .characterIndex = 4, .stringIndex = 1 } }, // 5 n "Beyond the tumultuous waters of the Lilac Bay" { .type = type::say, .say = { .characterIndex = 4, .stringIndex = 2 } }, // 6 n "And across the vast fields of Alysen" - { .type = type::play, .play = { .audioIndex = 2, /* FIXME channel */ } }, // 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::scene, .scene = { .imageIndex = 1 } }, // 9 bgforest1 { .type = type::dissolve, .dissolve = { .duration = 3.0 } }, // 10 @@ -267,220 +266,219 @@ const language::statement statements[] = { { .type = type::say, .say = { .characterIndex = 2, .stringIndex = 17 } }, // 31 e "Why yes, If I remember correctly, it should be just up ahead" { .type = type::stop, .stop = { /* FIXME channel */ } }, // 32 { .type = type::scene_color, .scene_color = { .color = 0xffffff } }, // 33 bgwhite - { .type = type::play, .play = { .audioIndex = 0, /* FIXME channel */ } }, // 34 sfx/Chime.ogg + { .type = type::play, .play = { .audioIndex = 0 } }, // 34 sfx/Chime.ogg { .type = type::dissolve, .dissolve = { .duration = 1.0 } }, // 35 - { .type = type::voice, .voice = { .audioIndex = 3 } }, // 36 n5test.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::play, .play = { .audioIndex = 4, /* FIXME channel */ } }, // 38 music/PhrygianButterflies.ogg - { .type = type::scene, .scene = { .imageIndex = 3 } }, // 39 bgflower1 - { .type = type::dissolve, .dissolve = { .duration = 1.0 } }, // 40 - { .type = type::show, .show = { .imageIndex = 7, .transformIndex = transform::right } }, // 41 ei - { .type = type::say, .say = { .characterIndex = 2, .stringIndex = 19 } }, // 42 e "Look at all the butterflies! They are all so pretty!" - { .type = type::show, .show = { .imageIndex = 8, .transformIndex = transform::left } }, // 43 al - { .type = type::say, .say = { .characterIndex = 0, .stringIndex = 20 } }, // 44 a "This place is like a dream..." - { .type = type::say, .say = { .characterIndex = 2, .stringIndex = 21 } }, // 45 e "There are so many flowers this time of year" - { .type = type::say, .say = { .characterIndex = 2, .stringIndex = 22 } }, // 46 e "I told you it would be worth the journey!" - { .type = type::say, .say = { .characterIndex = 0, .stringIndex = 23 } }, // 47 a "Can we stop for a bit now?" - { .type = type::say, .say = { .characterIndex = 2, .stringIndex = 24 } }, // 48 e "Of course" - { .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 = 0, .stringIndex = 26 } }, // 50 a "I told you not to eat them all!" - { .type = type::say, .say = { .characterIndex = 2, .stringIndex = 27 } }, // 51 e "Yah yah" - { .type = type::say, .say = { .characterIndex = 2, .stringIndex = 28 } }, // 52 e "Anyways, shall I recite a tale?" - { .type = type::menu, .menu = { .count = 2, .optionIndex = 2 } }, // 53 "Good idea", "I am too tired" - { .type = type::stop, .stop = { /* FIXME channel */ } }, // 54 - { .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 = 2, .stringIndex = 30 } }, // 56 e "Sure" - { .type = type::say, .say = { .characterIndex = 0, .stringIndex = 31 } }, // 57 a "..." - { .type = type::play, .play = { .audioIndex = 5, /* FIXME channel */ } }, // 58 music/Poem1.ogg - { .type = type::pause, .pause = { .duration = 40 } }, // 59 - { .type = type::jump, .jump = { .statementIndex = 65 } }, // 60 internal jump (b'__menu_end', 1) - { .type = type::say, .say = { .characterIndex = 2, .stringIndex = 32 } }, // 61 e "Serves you right for scaring those elephant-dogs" - { .type = type::stop, .stop = { /* FIXME channel */ } }, // 62 - { .type = type::say, .say = { .characterIndex = 0, .stringIndex = 33 } }, // 63 a "They were asking for it, you know" - { .type = type::jump, .jump = { .statementIndex = 65 } }, // 64 internal jump (b'__menu_end', 1) - { .type = type::jump, .jump = { .statementIndex = 66 } }, // 65 mainbranch2 - { .type = type::hide, .hide = { .imageIndex = 7 } }, // 66 ei - { .type = type::show, .show = { .imageIndex = 6, .transformIndex = transform::right } }, // 67 catw - { .type = type::show, .show = { .imageIndex = 7, .transformIndex = transform::centerleft } }, // 68 ei - { .type = type::voice, .voice = { .audioIndex = 6 } }, // 69 placeholdermeow.mp3 - { .type = type::say, .say = { .characterIndex = 1, .stringIndex = 34 } }, // 70 c "Rawrrrr" - { .type = type::hide, .hide = { .imageIndex = 6 } }, // 71 catw - { .type = type::show, .show = { .imageIndex = 5, .transformIndex = transform::right } }, // 72 cat - { .type = type::play, .play = { .audioIndex = 7, /* FIXME channel */ } }, // 73 music/ScaredMice.ogg - { .type = type::say, .say = { .characterIndex = 3, .stringIndex = 35 } }, // 74 mg "AHHHHHHHHHH!!!!!" - { .type = type::say, .say = { .characterIndex = 1, .stringIndex = 36 } }, // 75 c "Nyanyanyanya" - { .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::menu, .menu = { .count = 2, .optionIndex = 4 } }, // 77 "Beg for mercy", "Run" - { .type = type::say, .say = { .characterIndex = 0, .stringIndex = 38 } }, // 78 a "Please don't eat us!!!" - { .type = type::jump, .jump = { .statementIndex = 83 } }, // 79 internal jump (b'__menu_end', 2) - { .type = type::say, .say = { .characterIndex = 2, .stringIndex = 39 } }, // 80 e "Alice don't run, our only chance is through pleading!" - { .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 internal jump (b'__menu_end', 2) - { .type = type::jump, .jump = { .statementIndex = 84 } }, // 83 mainbranch3 - { .type = type::stop, .stop = { /* FIXME channel */ } }, // 84 - { .type = type::say, .say = { .characterIndex = 1, .stringIndex = 41 } }, // 85 c "I'm not gonna eat you nyanyanya" - { .type = type::play, .play = { .audioIndex = 2, /* FIXME channel */ } }, // 86 music/TinyForestMinstrels.ogg - { .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 = 1, .stringIndex = 43 } }, // 88 c "Also, are you minstrels?" - { .type = type::say, .say = { .characterIndex = 2, .stringIndex = 44 } }, // 89 e "Y-Yes" - { .type = type::say, .say = { .characterIndex = 0, .stringIndex = 45 } }, // 90 a "W-We are on a quest to Castle Alysen..." - { .type = type::say, .say = { .characterIndex = 2, .stringIndex = 46 } }, // 91 e "Shh don't tell her that" - { .type = type::say, .say = { .characterIndex = 1, .stringIndex = 47 } }, // 92 c "The Castle of Alysen you say?!?" - { .type = type::say, .say = { .characterIndex = 1, .stringIndex = 48 } }, // 93 c "Why, that's where I am headed!" - { .type = type::say, .say = { .characterIndex = 2, .stringIndex = 49 } }, // 94 e "You don't say..." - { .type = type::say, .say = { .characterIndex = 1, .stringIndex = 50 } }, // 95 c "Yah, I do actually" - { .type = type::say, .say = { .characterIndex = 2, .stringIndex = 51 } }, // 96 e "So... Why might you be traveling to the castle?" - { .type = type::say, .say = { .characterIndex = 1, .stringIndex = 52 } }, // 97 c "I belong to the lineage of Agrepen" - { .type = type::say, .say = { .characterIndex = 2, .stringIndex = 53 } }, // 98 e "And what might that mean?" - { .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 = 2, .stringIndex = 55 } }, // 100 e "Really? That must mean you are a noble?" - { .type = type::say, .say = { .characterIndex = 1, .stringIndex = 56 } }, // 101 c "Well, not really..." - { .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 = 58 } }, // 103 e "Ah I see" - { .type = type::say, .say = { .characterIndex = 2, .stringIndex = 59 } }, // 104 e "So do you live at the castle or something?" - { .type = type::say, .say = { .characterIndex = 1, .stringIndex = 60 } }, // 105 c "Well, no..." - { .type = type::say, .say = { .characterIndex = 0, .stringIndex = 61 } }, // 106 a "Then why are you traveling to Castle Alysen?" - { .type = type::say, .say = { .characterIndex = 1, .stringIndex = 62 } }, // 107 c "uhhh" - { .type = type::play, .play = { .audioIndex = 1, /* FIXME channel */ } }, // 108 sfx/MistAmbience.ogg - { .type = type::stop, .stop = { /* FIXME channel */ } }, // 109 - { .type = type::say, .say = { .characterIndex = 1, .stringIndex = 63 } }, // 110 c "I DONT NEED TO BE PRESSURED BY LITTLE MICE TO SAY ANYTHING!!!!" - { .type = type::say, .say = { .characterIndex = 1, .stringIndex = 64 } }, // 111 c "GOOD DAY!" - { .type = type::hide, .hide = { .imageIndex = 5 } }, // 112 cat - { .type = type::say, .say = { .characterIndex = 0, .stringIndex = 65 } }, // 113 a "Wha..." - { .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 = 0, .stringIndex = 67 } }, // 115 a "She didn't seem so bad" - { .type = type::say, .say = { .characterIndex = 2, .stringIndex = 68 } }, // 116 e "Are you kidding? She's a crazy kitty!" - { .type = type::scene_color, .scene_color = { .color = 0xffffff } }, // 117 bgwhite - { .type = type::play, .play = { .audioIndex = 0, /* FIXME channel */ } }, // 118 sfx/Chime.ogg - { .type = type::dissolve, .dissolve = { .duration = 3.0 } }, // 119 - { .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::scene, .scene = { .imageIndex = 2 } }, // 121 bgforest2 - { .type = type::dissolve, .dissolve = { .duration = 3.0 } }, // 122 - { .type = type::show, .show = { .imageIndex = 7, .transformIndex = transform::right } }, // 123 ei - { .type = type::say, .say = { .characterIndex = 2, .stringIndex = 70 } }, // 124 e "I think this is the right way..." - { .type = type::show, .show = { .imageIndex = 8, .transformIndex = transform::left } }, // 125 al - { .type = type::say, .say = { .characterIndex = 0, .stringIndex = 71 } }, // 126 a "Then where did the path go?" - { .type = type::say, .say = { .characterIndex = 2, .stringIndex = 72 } }, // 127 e "How am I supposed to know?" - { .type = type::say, .say = { .characterIndex = 0, .stringIndex = 73 } }, // 128 a "Did you hear that?!?!" - { .type = type::show, .show = { .imageIndex = 7, .transformIndex = transform::centerleft } }, // 129 ei - { .type = type::show, .show = { .imageIndex = 5, .transformIndex = transform::right } }, // 130 cat - { .type = type::play, .play = { .audioIndex = 4, /* FIXME channel */ } }, // 131 music/PhrygianButterflies.ogg - { .type = type::say, .say = { .characterIndex = 1, .stringIndex = 74 } }, // 132 c "Hey there..." - { .type = type::say, .say = { .characterIndex = 1, .stringIndex = 75 } }, // 133 c "I apologize" - { .type = type::say, .say = { .characterIndex = 1, .stringIndex = 76 } }, // 134 c "I didn't mean to storm off like that" - { .type = type::say, .say = { .characterIndex = 2, .stringIndex = 77 } }, // 135 e "Ha ha, no problem..." - { .type = type::say, .say = { .characterIndex = 0, .stringIndex = 78 } }, // 136 a "So... Why are you traveling to Castle Alysen?" - { .type = type::say, .say = { .characterIndex = 2, .stringIndex = 79 } }, // 137 e "Alice!!!" - { .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 = 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 = 1, .stringIndex = 82 } }, // 140 c "Though I know not what what she has summoned me for" - { .type = type::say, .say = { .characterIndex = 0, .stringIndex = 83 } }, // 141 a "Ahhhhhh" - { .type = type::say, .say = { .characterIndex = 1, .stringIndex = 84 } }, // 142 c "So then..." - { .type = type::say, .say = { .characterIndex = 1, .stringIndex = 85 } }, // 143 c "Why are YOU traveling to the Castle?" - { .type = type::say, .say = { .characterIndex = 0, .stringIndex = 86 } }, // 144 a "We are delivering a feather!!!" - { .type = type::say, .say = { .characterIndex = 2, .stringIndex = 87 } }, // 145 e "Alice no!" - { .type = type::say, .say = { .characterIndex = 0, .stringIndex = 88 } }, // 146 a "A feather that belonged to the queen herself!!!" - { .type = type::say, .say = { .characterIndex = 2, .stringIndex = 89 } }, // 147 e "Why you little..." - { .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 = 91 } }, // 149 c "How on the face of Al Mot might you have aquired such a thing?" - { .type = type::say, .say = { .characterIndex = 1, .stringIndex = 92 } }, // 150 c "If it is authentic, that is..." - { .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 = 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 = 95 } }, // 153 e "Eventually word spread to greater nearby settlements, and so" - { .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 = 97 } }, // 155 e "Four moons ago, the request was answered" - { .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 = 2, .stringIndex = 99 } }, // 157 e "Anyways, long story short, we drove those barbaric rats out of their home" - { .type = type::say, .say = { .characterIndex = 0, .stringIndex = 100 } }, // 158 a "They arent actual rats you know" - { .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 = 0, .stringIndex = 102 } }, // 160 a "And you forgot the most important part" - { .type = type::say, .say = { .characterIndex = 2, .stringIndex = 103 } }, // 161 e "Yah yah, I am getting there" - { .type = type::say, .say = { .characterIndex = 2, .stringIndex = 104 } }, // 162 e "So, essentially, my brother is trained in archery, and..." - { .type = type::say, .say = { .characterIndex = 0, .stringIndex = 105 } }, // 163 a "Speed it up already" - { .type = type::say, .say = { .characterIndex = 2, .stringIndex = 106 } }, // 164 e "You tell it then!" - { .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 = 1, .stringIndex = 108 } }, // 166 c "How do you know it belongs to the queen?" - { .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 = 0, .stringIndex = 110 } }, // 168 a "Supposedly, it was in a room filled with treasures!" - { .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 = 1, .stringIndex = 112 } }, // 170 c "Do you expect every bird in Avia to respect your alliance with Castle Alysen?" - { .type = type::say, .say = { .characterIndex = 2, .stringIndex = 113 } }, // 171 e "What do you mean?" - { .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 = 0, .stringIndex = 115 } }, // 173 a "I could go for some dinner..." - { .type = type::say, .say = { .characterIndex = 2, .stringIndex = 116 } }, // 174 e "Anyways..." - { .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 = 118 } }, // 176 e "So... Yesterday, after sundown" - { .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 = 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 = 2, .stringIndex = 121 } }, // 179 e "But so are we!" - { .type = type::say, .say = { .characterIndex = 0, .stringIndex = 122 } }, // 180 a "Hahahaha" - { .type = type::say, .say = { .characterIndex = 1, .stringIndex = 123 } }, // 181 c "Are the two of you mad?" - { .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 = 0, .stringIndex = 125 } }, // 183 a "Yes, we intend to deliver the feather to its rightful owner" - { .type = type::say, .say = { .characterIndex = 1, .stringIndex = 126 } }, // 184 c "Absolute madness!" - { .type = type::say, .say = { .characterIndex = 3, .stringIndex = 31 } }, // 185 mg "..." - { .type = type::say, .say = { .characterIndex = 1, .stringIndex = 127 } }, // 186 c "I will follow the two of you" - { .type = type::say, .say = { .characterIndex = 1, .stringIndex = 128 } }, // 187 c "To keep you safe, that is" - { .type = type::say, .say = { .characterIndex = 0, .stringIndex = 129 } }, // 188 a "Alright!" - { .type = type::say, .say = { .characterIndex = 2, .stringIndex = 130 } }, // 189 e "Ha ha... Okay..." - { .type = type::say, .say = { .characterIndex = 1, .stringIndex = 131 } }, // 190 c "Great! Follow me, I know a shortcut! :3" - { .type = type::hide, .hide = { .imageIndex = 5 } }, // 191 cat - { .type = type::say, .say = { .characterIndex = 0, .stringIndex = 132 } }, // 192 a "Sounds good!" - { .type = type::hide, .hide = { .imageIndex = 8 } }, // 193 al - { .type = type::stop, .stop = { /* FIXME channel */ } }, // 194 - { .type = type::say, .say = { .characterIndex = 2, .stringIndex = 133 } }, // 195 e "Oh dear!" - { .type = type::hide, .hide = { .imageIndex = 7 } }, // 196 ei - { .type = type::scene_color, .scene_color = { .color = 0xffffff } }, // 197 bgwhite - { .type = type::play, .play = { .audioIndex = 0, /* FIXME channel */ } }, // 198 sfx/Chime.ogg - { .type = type::dissolve, .dissolve = { .duration = 2.0 } }, // 199 - { .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::scene, .scene = { .imageIndex = 4 } }, // 201 bgwheatfield1 - { .type = type::play, .play = { .audioIndex = 8, /* FIXME channel */ } }, // 202 music/WheatFields.ogg - { .type = type::show, .show = { .imageIndex = 5, .transformIndex = transform::right } }, // 203 cat - { .type = type::dissolve, .dissolve = { .duration = 1.3 } }, // 204 - { .type = type::say, .say = { .characterIndex = 1, .stringIndex = 135 } }, // 205 c "Nya" - { .type = type::show, .show = { .imageIndex = 8, .transformIndex = transform::left } }, // 206 al - { .type = type::say, .say = { .characterIndex = 0, .stringIndex = 136 } }, // 207 a "Look, your right, the castle is just up ahead!" - { .type = type::show, .show = { .imageIndex = 7, .transformIndex = transform::centerleft } }, // 208 ei - { .type = type::say, .say = { .characterIndex = 2, .stringIndex = 137 } }, // 209 e "Wait up" - { .type = type::say, .say = { .characterIndex = 1, .stringIndex = 138 } }, // 210 c "I told you I knew a shortcut!" - { .type = type::say, .say = { .characterIndex = 1, .stringIndex = 139 } }, // 211 c "Most people take the long way around" - { .type = type::say, .say = { .characterIndex = 2, .stringIndex = 140 } }, // 212 e "Yah because these are royal wheatfields!" - { .type = type::say, .say = { .characterIndex = 0, .stringIndex = 141 } }, // 213 a "Who cares?" - { .type = type::say, .say = { .characterIndex = 2, .stringIndex = 142 } }, // 214 e "Are you trying to get us killed?" - { .type = type::say, .say = { .characterIndex = 2, .stringIndex = 143 } }, // 215 e "Its trespassing on royal land!" - { .type = type::say, .say = { .characterIndex = 1, .stringIndex = 144 } }, // 216 c "Calm down, I have done this a million times" - { .type = type::say, .say = { .characterIndex = 2, .stringIndex = 145 } }, // 217 e "That doesnt make me calm!" - { .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 = 1, .stringIndex = 147 } }, // 219 c "You little mice truly are mad!" - { .type = type::say, .say = { .characterIndex = 0, .stringIndex = 148 } }, // 220 a "I like the wheat!" - { .type = type::say, .say = { .characterIndex = 2, .stringIndex = 149 } }, // 221 e "Shut up!" - { .type = type::say, .say = { .characterIndex = 1, .stringIndex = 150 } }, // 222 c "Sounds like someone needs a nap!" - { .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 = 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 = 153 } }, // 225 c "The power of friendship wont protect the two of you from becoming dinner" - { .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 = 2, .stringIndex = 155 } }, // 227 e "Hey, we have a good reason!" - { .type = type::say, .say = { .characterIndex = 1, .stringIndex = 156 } }, // 228 c "And what might that be?" - { .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 = 158 } }, // 230 c "Pride has touched the chosen meouse" - { .type = type::say, .say = { .characterIndex = 1, .stringIndex = 159 } }, // 231 c "Flies she towards the Castle" - { .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 = 3, .stringIndex = 161 } }, // 233 mg "What?" - { .type = type::say, .say = { .characterIndex = 1, .stringIndex = 162 } }, // 234 c "Nyanyanya" - { .type = type::say, .say = { .characterIndex = 1, .stringIndex = 163 } }, // 235 c "Nyevermind" - { .type = type::say, .say = { .characterIndex = 1, .stringIndex = 164 } }, // 236 c "Sing me a song little minstrels!" - { .type = type::say, .say = { .characterIndex = 1, .stringIndex = 165 } }, // 237 c "Very Nyice!" - { .type = type::say, .say = { .characterIndex = 1, .stringIndex = 166 } }, // 238 c "Now tell me little minstrels, what are your names?" - { .type = type::say, .say = { .characterIndex = 0, .stringIndex = 167 } }, // 239 a "My name is Alice" - { .type = type::say, .say = { .characterIndex = 2, .stringIndex = 168 } }, // 240 e "And my name is Eily" - { .type = type::say, .say = { .characterIndex = 2, .stringIndex = 169 } }, // 241 e "What is your name?" - { .type = type::say, .say = { .characterIndex = 5, .stringIndex = 170 } }, // 242 l "My name is Leona!" - { .type = type::scene_color, .scene_color = { .color = 0xffffff } }, // 243 bgwhite - { .type = type::dissolve, .dissolve = { .duration = 3.0 } }, // 244 - { .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::say, .say = { .characterIndex = 4, .stringIndex = 172 } }, // 246 n "Upon approaching the castle walls" - { .type = type::_return }, // 247 + { .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::play, .play = { .audioIndex = 3 } }, // 37 music/PhrygianButterflies.ogg + { .type = type::scene, .scene = { .imageIndex = 3 } }, // 38 bgflower1 + { .type = type::dissolve, .dissolve = { .duration = 1.0 } }, // 39 + { .type = type::show, .show = { .imageIndex = 7, .transformIndex = transform::right } }, // 40 ei + { .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 = 8, .transformIndex = transform::left } }, // 42 al + { .type = type::say, .say = { .characterIndex = 0, .stringIndex = 20 } }, // 43 a "This place is like a dream..." + { .type = type::say, .say = { .characterIndex = 2, .stringIndex = 21 } }, // 44 e "There are so many flowers this time of year" + { .type = type::say, .say = { .characterIndex = 2, .stringIndex = 22 } }, // 45 e "I told you it would be worth the journey!" + { .type = type::say, .say = { .characterIndex = 0, .stringIndex = 23 } }, // 46 a "Can we stop for a bit now?" + { .type = type::say, .say = { .characterIndex = 2, .stringIndex = 24 } }, // 47 e "Of course" + { .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 = 0, .stringIndex = 26 } }, // 49 a "I told you not to eat them all!" + { .type = type::say, .say = { .characterIndex = 2, .stringIndex = 27 } }, // 50 e "Yah yah" + { .type = type::say, .say = { .characterIndex = 2, .stringIndex = 28 } }, // 51 e "Anyways, shall I recite a tale?" + { .type = type::menu, .menu = { .count = 2, .optionIndex = 2 } }, // 52 "Good idea", "I am too tired" + { .type = type::stop, .stop = { /* FIXME channel */ } }, // 53 + { .type = type::say, .say = { .characterIndex = 0, .stringIndex = 29 } }, // 54 a "Why dont you sing the story of Eleanor the Hero!" + { .type = type::say, .say = { .characterIndex = 2, .stringIndex = 30 } }, // 55 e "Sure" + { .type = type::say, .say = { .characterIndex = 0, .stringIndex = 31 } }, // 56 a "..." + { .type = type::play, .play = { .audioIndex = 4 } }, // 57 music/Poem1.ogg + { .type = type::pause, .pause = { .duration = 40 } }, // 58 + { .type = type::jump, .jump = { .statementIndex = 64 } }, // 59 internal jump (b'__menu_end', 1) + { .type = type::say, .say = { .characterIndex = 2, .stringIndex = 32 } }, // 60 e "Serves you right for scaring those elephant-dogs" + { .type = type::stop, .stop = { /* FIXME channel */ } }, // 61 + { .type = type::say, .say = { .characterIndex = 0, .stringIndex = 33 } }, // 62 a "They were asking for it, you know" + { .type = type::jump, .jump = { .statementIndex = 64 } }, // 63 internal jump (b'__menu_end', 1) + { .type = type::jump, .jump = { .statementIndex = 65 } }, // 64 mainbranch2 + { .type = type::hide, .hide = { .imageIndex = 7 } }, // 65 ei + { .type = type::show, .show = { .imageIndex = 6, .transformIndex = transform::right } }, // 66 catw + { .type = type::show, .show = { .imageIndex = 7, .transformIndex = transform::centerleft } }, // 67 ei + { .type = type::voice, .voice = { .audioIndex = 5 } }, // 68 placeholdermeow.mp3 + { .type = type::say, .say = { .characterIndex = 1, .stringIndex = 34 } }, // 69 c "Rawrrrr" + { .type = type::hide, .hide = { .imageIndex = 6 } }, // 70 catw + { .type = type::show, .show = { .imageIndex = 5, .transformIndex = transform::right } }, // 71 cat + { .type = type::play, .play = { .audioIndex = 6 } }, // 72 music/ScaredMice.ogg + { .type = type::say, .say = { .characterIndex = 3, .stringIndex = 35 } }, // 73 mg "AHHHHHHHHHH!!!!!" + { .type = type::say, .say = { .characterIndex = 1, .stringIndex = 36 } }, // 74 c "Nyanyanyanya" + { .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::menu, .menu = { .count = 2, .optionIndex = 4 } }, // 76 "Beg for mercy", "Run" + { .type = type::say, .say = { .characterIndex = 0, .stringIndex = 38 } }, // 77 a "Please don't eat us!!!" + { .type = type::jump, .jump = { .statementIndex = 82 } }, // 78 internal jump (b'__menu_end', 2) + { .type = type::say, .say = { .characterIndex = 2, .stringIndex = 39 } }, // 79 e "Alice don't run, our only chance is through pleading!" + { .type = type::say, .say = { .characterIndex = 2, .stringIndex = 40 } }, // 80 e "Please don't eat us, miss kitty cat!!! ><" + { .type = type::jump, .jump = { .statementIndex = 82 } }, // 81 internal jump (b'__menu_end', 2) + { .type = type::jump, .jump = { .statementIndex = 83 } }, // 82 mainbranch3 + { .type = type::stop, .stop = { /* FIXME channel */ } }, // 83 + { .type = type::say, .say = { .characterIndex = 1, .stringIndex = 41 } }, // 84 c "I'm not gonna eat you nyanyanya" + { .type = type::play, .play = { .audioIndex = 2 } }, // 85 music/TinyForestMinstrels.ogg + { .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::say, .say = { .characterIndex = 1, .stringIndex = 43 } }, // 87 c "Also, are you minstrels?" + { .type = type::say, .say = { .characterIndex = 2, .stringIndex = 44 } }, // 88 e "Y-Yes" + { .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 = 46 } }, // 90 e "Shh don't tell her that" + { .type = type::say, .say = { .characterIndex = 1, .stringIndex = 47 } }, // 91 c "The Castle of Alysen you say?!?" + { .type = type::say, .say = { .characterIndex = 1, .stringIndex = 48 } }, // 92 c "Why, that's where I am headed!" + { .type = type::say, .say = { .characterIndex = 2, .stringIndex = 49 } }, // 93 e "You don't say..." + { .type = type::say, .say = { .characterIndex = 1, .stringIndex = 50 } }, // 94 c "Yah, I do actually" + { .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 = 52 } }, // 96 c "I belong to the lineage of Agrepen" + { .type = type::say, .say = { .characterIndex = 2, .stringIndex = 53 } }, // 97 e "And what might that mean?" + { .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 = 55 } }, // 99 e "Really? That must mean you are a noble?" + { .type = type::say, .say = { .characterIndex = 1, .stringIndex = 56 } }, // 100 c "Well, not really..." + { .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 = 2, .stringIndex = 58 } }, // 102 e "Ah I see" + { .type = type::say, .say = { .characterIndex = 2, .stringIndex = 59 } }, // 103 e "So do you live at the castle or something?" + { .type = type::say, .say = { .characterIndex = 1, .stringIndex = 60 } }, // 104 c "Well, no..." + { .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 = 62 } }, // 106 c "uhhh" + { .type = type::play, .play = { .audioIndex = 1 } }, // 107 sfx/MistAmbience.ogg + { .type = type::stop, .stop = { /* FIXME channel */ } }, // 108 + { .type = type::say, .say = { .characterIndex = 1, .stringIndex = 63 } }, // 109 c "I DONT NEED TO BE PRESSURED BY LITTLE MICE TO SAY ANYTHING!!!!" + { .type = type::say, .say = { .characterIndex = 1, .stringIndex = 64 } }, // 110 c "GOOD DAY!" + { .type = type::hide, .hide = { .imageIndex = 5 } }, // 111 cat + { .type = type::say, .say = { .characterIndex = 0, .stringIndex = 65 } }, // 112 a "Wha..." + { .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 = 67 } }, // 114 a "She didn't seem so bad" + { .type = type::say, .say = { .characterIndex = 2, .stringIndex = 68 } }, // 115 e "Are you kidding? She's a crazy kitty!" + { .type = type::scene_color, .scene_color = { .color = 0xffffff } }, // 116 bgwhite + { .type = type::play, .play = { .audioIndex = 0 } }, // 117 sfx/Chime.ogg + { .type = type::dissolve, .dissolve = { .duration = 3.0 } }, // 118 + { .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::scene, .scene = { .imageIndex = 2 } }, // 120 bgforest2 + { .type = type::dissolve, .dissolve = { .duration = 3.0 } }, // 121 + { .type = type::show, .show = { .imageIndex = 7, .transformIndex = transform::right } }, // 122 ei + { .type = type::say, .say = { .characterIndex = 2, .stringIndex = 70 } }, // 123 e "I think this is the right way..." + { .type = type::show, .show = { .imageIndex = 8, .transformIndex = transform::left } }, // 124 al + { .type = type::say, .say = { .characterIndex = 0, .stringIndex = 71 } }, // 125 a "Then where did the path go?" + { .type = type::say, .say = { .characterIndex = 2, .stringIndex = 72 } }, // 126 e "How am I supposed to know?" + { .type = type::say, .say = { .characterIndex = 0, .stringIndex = 73 } }, // 127 a "Did you hear that?!?!" + { .type = type::show, .show = { .imageIndex = 7, .transformIndex = transform::centerleft } }, // 128 ei + { .type = type::show, .show = { .imageIndex = 5, .transformIndex = transform::right } }, // 129 cat + { .type = type::play, .play = { .audioIndex = 3 } }, // 130 music/PhrygianButterflies.ogg + { .type = type::say, .say = { .characterIndex = 1, .stringIndex = 74 } }, // 131 c "Hey there..." + { .type = type::say, .say = { .characterIndex = 1, .stringIndex = 75 } }, // 132 c "I apologize" + { .type = type::say, .say = { .characterIndex = 1, .stringIndex = 76 } }, // 133 c "I didn't mean to storm off like that" + { .type = type::say, .say = { .characterIndex = 2, .stringIndex = 77 } }, // 134 e "Ha ha, no problem..." + { .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 = 79 } }, // 136 e "Alice!!!" + { .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 = 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 = 82 } }, // 139 c "Though I know not what what she has summoned me for" + { .type = type::say, .say = { .characterIndex = 0, .stringIndex = 83 } }, // 140 a "Ahhhhhh" + { .type = type::say, .say = { .characterIndex = 1, .stringIndex = 84 } }, // 141 c "So then..." + { .type = type::say, .say = { .characterIndex = 1, .stringIndex = 85 } }, // 142 c "Why are YOU traveling to the Castle?" + { .type = type::say, .say = { .characterIndex = 0, .stringIndex = 86 } }, // 143 a "We are delivering a feather!!!" + { .type = type::say, .say = { .characterIndex = 2, .stringIndex = 87 } }, // 144 e "Alice no!" + { .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 = 89 } }, // 146 e "Why you little..." + { .type = type::say, .say = { .characterIndex = 1, .stringIndex = 90 } }, // 147 c "A feather you say? One of the queens?" + { .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 = 92 } }, // 149 c "If it is authentic, that is..." + { .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 = 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 = 95 } }, // 152 e "Eventually word spread to greater nearby settlements, and so" + { .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 = 97 } }, // 154 e "Four moons ago, the request was answered" + { .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 = 99 } }, // 156 e "Anyways, long story short, we drove those barbaric rats out of their home" + { .type = type::say, .say = { .characterIndex = 0, .stringIndex = 100 } }, // 157 a "They arent actual rats you know" + { .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 = 102 } }, // 159 a "And you forgot the most important part" + { .type = type::say, .say = { .characterIndex = 2, .stringIndex = 103 } }, // 160 e "Yah yah, I am getting there" + { .type = type::say, .say = { .characterIndex = 2, .stringIndex = 104 } }, // 161 e "So, essentially, my brother is trained in archery, and..." + { .type = type::say, .say = { .characterIndex = 0, .stringIndex = 105 } }, // 162 a "Speed it up already" + { .type = type::say, .say = { .characterIndex = 2, .stringIndex = 106 } }, // 163 e "You tell it then!" + { .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 = 1, .stringIndex = 108 } }, // 165 c "How do you know it belongs to the queen?" + { .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 = 0, .stringIndex = 110 } }, // 167 a "Supposedly, it was in a room filled with treasures!" + { .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 = 1, .stringIndex = 112 } }, // 169 c "Do you expect every bird in Avia to respect your alliance with Castle Alysen?" + { .type = type::say, .say = { .characterIndex = 2, .stringIndex = 113 } }, // 170 e "What do you mean?" + { .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 = 0, .stringIndex = 115 } }, // 172 a "I could go for some dinner..." + { .type = type::say, .say = { .characterIndex = 2, .stringIndex = 116 } }, // 173 e "Anyways..." + { .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 = 118 } }, // 175 e "So... Yesterday, after sundown" + { .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 = 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 = 121 } }, // 178 e "But so are we!" + { .type = type::say, .say = { .characterIndex = 0, .stringIndex = 122 } }, // 179 a "Hahahaha" + { .type = type::say, .say = { .characterIndex = 1, .stringIndex = 123 } }, // 180 c "Are the two of you mad?" + { .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 = 0, .stringIndex = 125 } }, // 182 a "Yes, we intend to deliver the feather to its rightful owner" + { .type = type::say, .say = { .characterIndex = 1, .stringIndex = 126 } }, // 183 c "Absolute madness!" + { .type = type::say, .say = { .characterIndex = 3, .stringIndex = 31 } }, // 184 mg "..." + { .type = type::say, .say = { .characterIndex = 1, .stringIndex = 127 } }, // 185 c "I will follow the two of you" + { .type = type::say, .say = { .characterIndex = 1, .stringIndex = 128 } }, // 186 c "To keep you safe, that is" + { .type = type::say, .say = { .characterIndex = 0, .stringIndex = 129 } }, // 187 a "Alright!" + { .type = type::say, .say = { .characterIndex = 2, .stringIndex = 130 } }, // 188 e "Ha ha... Okay..." + { .type = type::say, .say = { .characterIndex = 1, .stringIndex = 131 } }, // 189 c "Great! Follow me, I know a shortcut! :3" + { .type = type::hide, .hide = { .imageIndex = 5 } }, // 190 cat + { .type = type::say, .say = { .characterIndex = 0, .stringIndex = 132 } }, // 191 a "Sounds good!" + { .type = type::hide, .hide = { .imageIndex = 8 } }, // 192 al + { .type = type::stop, .stop = { /* FIXME channel */ } }, // 193 + { .type = type::say, .say = { .characterIndex = 2, .stringIndex = 133 } }, // 194 e "Oh dear!" + { .type = type::hide, .hide = { .imageIndex = 7 } }, // 195 ei + { .type = type::scene_color, .scene_color = { .color = 0xffffff } }, // 196 bgwhite + { .type = type::play, .play = { .audioIndex = 0 } }, // 197 sfx/Chime.ogg + { .type = type::dissolve, .dissolve = { .duration = 2.0 } }, // 198 + { .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::scene, .scene = { .imageIndex = 4 } }, // 200 bgwheatfield1 + { .type = type::play, .play = { .audioIndex = 7 } }, // 201 music/WheatFields.ogg + { .type = type::show, .show = { .imageIndex = 5, .transformIndex = transform::right } }, // 202 cat + { .type = type::dissolve, .dissolve = { .duration = 1.3 } }, // 203 + { .type = type::say, .say = { .characterIndex = 1, .stringIndex = 135 } }, // 204 c "Nya" + { .type = type::show, .show = { .imageIndex = 8, .transformIndex = transform::left } }, // 205 al + { .type = type::say, .say = { .characterIndex = 0, .stringIndex = 136 } }, // 206 a "Look, your right, the castle is just up ahead!" + { .type = type::show, .show = { .imageIndex = 7, .transformIndex = transform::centerleft } }, // 207 ei + { .type = type::say, .say = { .characterIndex = 2, .stringIndex = 137 } }, // 208 e "Wait up" + { .type = type::say, .say = { .characterIndex = 1, .stringIndex = 138 } }, // 209 c "I told you I knew a shortcut!" + { .type = type::say, .say = { .characterIndex = 1, .stringIndex = 139 } }, // 210 c "Most people take the long way around" + { .type = type::say, .say = { .characterIndex = 2, .stringIndex = 140 } }, // 211 e "Yah because these are royal wheatfields!" + { .type = type::say, .say = { .characterIndex = 0, .stringIndex = 141 } }, // 212 a "Who cares?" + { .type = type::say, .say = { .characterIndex = 2, .stringIndex = 142 } }, // 213 e "Are you trying to get us killed?" + { .type = type::say, .say = { .characterIndex = 2, .stringIndex = 143 } }, // 214 e "Its trespassing on royal land!" + { .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 = 145 } }, // 216 e "That doesnt make me calm!" + { .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 = 1, .stringIndex = 147 } }, // 218 c "You little mice truly are mad!" + { .type = type::say, .say = { .characterIndex = 0, .stringIndex = 148 } }, // 219 a "I like the wheat!" + { .type = type::say, .say = { .characterIndex = 2, .stringIndex = 149 } }, // 220 e "Shut up!" + { .type = type::say, .say = { .characterIndex = 1, .stringIndex = 150 } }, // 221 c "Sounds like someone needs a nap!" + { .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 = 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 = 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 = 154 } }, // 225 c "And that, is why I feel obligated to accompany you!" + { .type = type::say, .say = { .characterIndex = 2, .stringIndex = 155 } }, // 226 e "Hey, we have a good reason!" + { .type = type::say, .say = { .characterIndex = 1, .stringIndex = 156 } }, // 227 c "And what might that be?" + { .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 = 158 } }, // 229 c "Pride has touched the chosen meouse" + { .type = type::say, .say = { .characterIndex = 1, .stringIndex = 159 } }, // 230 c "Flies she towards the Castle" + { .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 = 3, .stringIndex = 161 } }, // 232 mg "What?" + { .type = type::say, .say = { .characterIndex = 1, .stringIndex = 162 } }, // 233 c "Nyanyanya" + { .type = type::say, .say = { .characterIndex = 1, .stringIndex = 163 } }, // 234 c "Nyevermind" + { .type = type::say, .say = { .characterIndex = 1, .stringIndex = 164 } }, // 235 c "Sing me a song little minstrels!" + { .type = type::say, .say = { .characterIndex = 1, .stringIndex = 165 } }, // 236 c "Very Nyice!" + { .type = type::say, .say = { .characterIndex = 1, .stringIndex = 166 } }, // 237 c "Now tell me little minstrels, what are your names?" + { .type = type::say, .say = { .characterIndex = 0, .stringIndex = 167 } }, // 238 a "My name is Alice" + { .type = type::say, .say = { .characterIndex = 2, .stringIndex = 168 } }, // 239 e "And my name is Eily" + { .type = type::say, .say = { .characterIndex = 2, .stringIndex = 169 } }, // 240 e "What is your name?" + { .type = type::say, .say = { .characterIndex = 5, .stringIndex = 170 } }, // 241 l "My name is Leona!" + { .type = type::scene_color, .scene_color = { .color = 0xffffff } }, // 242 bgwhite + { .type = type::dissolve, .dissolve = { .duration = 3.0 } }, // 243 + { .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::say, .say = { .characterIndex = 4, .stringIndex = 172 } }, // 245 n "Upon approaching the castle walls" + { .type = type::_return }, // 246 }; const int statements_length = (sizeof (statements)) / (sizeof (statements[0]));