renpy: pause and dissolve
This commit is contained in:
parent
4ead8403f3
commit
bb10732ce1
8
Makefile
8
Makefile
@ -70,6 +70,7 @@ OBJS = \
|
|||||||
src/tga/tga.o \
|
src/tga/tga.o \
|
||||||
src/font/outline.o \
|
src/font/outline.o \
|
||||||
src/renpy/vulkan.o \
|
src/renpy/vulkan.o \
|
||||||
|
src/renpy/composite/vulkan.o \
|
||||||
src/renpy/script.o \
|
src/renpy/script.o \
|
||||||
src/renpy/interpreter.o \
|
src/renpy/interpreter.o \
|
||||||
src/renpy/interact.o \
|
src/renpy/interact.o \
|
||||||
@ -130,8 +131,8 @@ all: main
|
|||||||
main: $(OBJS) $(LIBS)
|
main: $(OBJS) $(LIBS)
|
||||||
$(CC) $(ARCH) $(LDFLAGS) $(FLAGS) $(OPT) $(DEBUG) $^ -o $@
|
$(CC) $(ARCH) $(LDFLAGS) $(FLAGS) $(OPT) $(DEBUG) $^ -o $@
|
||||||
|
|
||||||
#%.spv: %.hlsl
|
%.spv: %.hlsl
|
||||||
# ../dxc/bin/dxc -spirv -T lib_6_3 -fspv-target-env=vulkan1.3 $< -Fo $@
|
../dxc/bin/dxc -spirv -T lib_6_3 -fspv-target-env=vulkan1.3 $< -Fo $@
|
||||||
|
|
||||||
tool/pack_file: tool/pack_file.cpp
|
tool/pack_file: tool/pack_file.cpp
|
||||||
make -C tool pack_file
|
make -C tool pack_file
|
||||||
@ -141,6 +142,9 @@ tool/pack_file: tool/pack_file.cpp
|
|||||||
|
|
||||||
src/pack.o: files.pack.zlib
|
src/pack.o: files.pack.zlib
|
||||||
|
|
||||||
|
#src/renpy/script.cpp: data/renpy/script.rpy
|
||||||
|
# PYTHONPATH=renpy-parser python -m transform $< > $@
|
||||||
|
|
||||||
PACK_FILENAMES = $(shell cat filenames.txt)
|
PACK_FILENAMES = $(shell cat filenames.txt)
|
||||||
files.pack: tool/pack_file $(PACK_FILENAMES) filenames.txt
|
files.pack: tool/pack_file $(PACK_FILENAMES) filenames.txt
|
||||||
./tool/pack_file $@ $(PACK_FILENAMES)
|
./tool/pack_file $@ $(PACK_FILENAMES)
|
||||||
|
|||||||
@ -3,6 +3,7 @@
|
|||||||
# Declare characters used by this game. The color argument colorizes the
|
# Declare characters used by this game. The color argument colorizes the
|
||||||
# name of the character.
|
# name of the character.
|
||||||
image bgwhite = "#ffffff"
|
image bgwhite = "#ffffff"
|
||||||
|
image bgblack = "#000000"
|
||||||
image bgforest1 = "bg/forest1.png"
|
image bgforest1 = "bg/forest1.png"
|
||||||
image bgforest2 = "bg/forest2.png"
|
image bgforest2 = "bg/forest2.png"
|
||||||
image bgflower1 = "bg/flowerfield1.png"
|
image bgflower1 = "bg/flowerfield1.png"
|
||||||
@ -62,6 +63,8 @@ label start:
|
|||||||
#play Chime "sfx/Chime.ogg" fadeout 1.0
|
#play Chime "sfx/Chime.ogg" fadeout 1.0
|
||||||
play sound "sfx/Chime.ogg"
|
play sound "sfx/Chime.ogg"
|
||||||
play MistAmbience "sfx/MistAmbience.ogg"
|
play MistAmbience "sfx/MistAmbience.ogg"
|
||||||
|
scene bgblack
|
||||||
|
pause 0.0
|
||||||
scene bgwhite
|
scene bgwhite
|
||||||
with Dissolve(3.0)
|
with Dissolve(3.0)
|
||||||
#play music "IntroMusicTest.ogg"
|
#play music "IntroMusicTest.ogg"
|
||||||
|
|||||||
@ -2,6 +2,7 @@ shader/font.spv
|
|||||||
data/font/outline/medieval_sharp_24.data
|
data/font/outline/medieval_sharp_24.data
|
||||||
|
|
||||||
shader/renpy.spv
|
shader/renpy.spv
|
||||||
|
shader/renpy_composite.spv
|
||||||
data/renpy/images/flowers.dds
|
data/renpy/images/flowers.dds
|
||||||
data/renpy/images/bg/forest1.dds
|
data/renpy/images/bg/forest1.dds
|
||||||
data/renpy/images/bg/forest2.dds
|
data/renpy/images/bg/forest2.dds
|
||||||
|
|||||||
@ -110,15 +110,15 @@ namespace font::outline {
|
|||||||
int& outputIndex,
|
int& outputIndex,
|
||||||
int startIndex,
|
int startIndex,
|
||||||
int endIndex,
|
int endIndex,
|
||||||
uint32_t color);
|
uint32_t color) const;
|
||||||
void centered(int frameIndex, char const * const string, uint32_t& x, uint32_t& y,
|
void centered(int frameIndex, char const * const string, uint32_t& x, uint32_t& y,
|
||||||
uint32_t minX,
|
uint32_t minX,
|
||||||
uint32_t maxWidth,
|
uint32_t maxWidth,
|
||||||
int& outputIndex,
|
int& outputIndex,
|
||||||
uint32_t color);
|
uint32_t color) const;
|
||||||
void draw(VkCommandBuffer commandBuffer,
|
void draw(VkCommandBuffer commandBuffer,
|
||||||
uint32_t frameIndex,
|
uint32_t frameIndex,
|
||||||
renpy::interpreter const& state);
|
renpy::interpreter const& state) const;
|
||||||
|
|
||||||
LoadedFont load_font(font_desc const& desc);
|
LoadedFont load_font(font_desc const& desc);
|
||||||
};
|
};
|
||||||
|
|||||||
52
include/renpy/composite/vulkan.h
Normal file
52
include/renpy/composite/vulkan.h
Normal file
@ -0,0 +1,52 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
namespace renpy::composite {
|
||||||
|
|
||||||
|
struct vulkan {
|
||||||
|
static constexpr int perVertexSize = (4) * 2;
|
||||||
|
|
||||||
|
// externally initialized, opaque handle
|
||||||
|
VkInstance instance;
|
||||||
|
VkDevice device;
|
||||||
|
VkQueue queue;
|
||||||
|
VkCommandPool commandPool;
|
||||||
|
// externally initialized, structures
|
||||||
|
VkPhysicalDeviceProperties physicalDeviceProperties;
|
||||||
|
VkPhysicalDeviceMemoryProperties physicalDeviceMemoryProperties;
|
||||||
|
// externally initialized, enum
|
||||||
|
VkFormat colorFormat;
|
||||||
|
VkFormat depthFormat;
|
||||||
|
VkSampler linearSampler;
|
||||||
|
|
||||||
|
// internal vulkan state
|
||||||
|
VkPipelineLayout pipelineLayout;
|
||||||
|
VkShaderModule shaderModule;
|
||||||
|
VkPipeline pipeline;
|
||||||
|
VertexIndex vertexIndex;
|
||||||
|
|
||||||
|
VkDescriptorPool descriptorPool{ VK_NULL_HANDLE };
|
||||||
|
static constexpr int descriptorSetLayoutCount = 1;
|
||||||
|
VkDescriptorSetLayout descriptorSetLayouts[descriptorSetLayoutCount]; // unrelated to maxFrames, unrelated to descriptorCount
|
||||||
|
VkDescriptorSet descriptorSet0;
|
||||||
|
|
||||||
|
void initial_state(VkInstance instance,
|
||||||
|
VkDevice device,
|
||||||
|
VkQueue queue,
|
||||||
|
VkCommandPool commandPool,
|
||||||
|
VkPhysicalDeviceProperties physicalDeviceProperties,
|
||||||
|
VkPhysicalDeviceMemoryProperties physicalDeviceMemoryProperties,
|
||||||
|
VkFormat colorFormat,
|
||||||
|
VkFormat depthFormat,
|
||||||
|
VkSampler linearSampler);
|
||||||
|
void init();
|
||||||
|
void load_vertex_index_buffer();
|
||||||
|
void load_shader();
|
||||||
|
void create_descriptor_sets();
|
||||||
|
void write_descriptor_sets(VkImageView * imageViews, int imageViewCount);
|
||||||
|
void create_pipeline();
|
||||||
|
void draw(VkCommandBuffer commandBuffer,
|
||||||
|
uint32_t frameIndex,
|
||||||
|
float dissolveLerp,
|
||||||
|
float textLerp);
|
||||||
|
};
|
||||||
|
}
|
||||||
@ -3,6 +3,7 @@
|
|||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
|
|
||||||
#include "renpy/language.h"
|
#include "renpy/language.h"
|
||||||
|
#include "renpy/script.h"
|
||||||
|
|
||||||
namespace renpy {
|
namespace renpy {
|
||||||
struct top_left {
|
struct top_left {
|
||||||
@ -40,7 +41,15 @@ namespace renpy {
|
|||||||
uint32_t count;
|
uint32_t count;
|
||||||
uint32_t optionIndex;
|
uint32_t optionIndex;
|
||||||
} menu;
|
} menu;
|
||||||
bool interactionWait;
|
uint32_t dissolveIndex;
|
||||||
|
struct {
|
||||||
|
bool voice;
|
||||||
|
bool menu;
|
||||||
|
bool dissolve;
|
||||||
|
bool pause;
|
||||||
|
} pause;
|
||||||
|
double dissolveDuration;
|
||||||
|
double pauseDuration;
|
||||||
|
|
||||||
uint32_t findImage(uint32_t imageIndex);
|
uint32_t findImage(uint32_t imageIndex);
|
||||||
void showImage(uint32_t imageIndex, uint32_t transformIndex);
|
void showImage(uint32_t imageIndex, uint32_t transformIndex);
|
||||||
@ -48,5 +57,15 @@ namespace renpy {
|
|||||||
void reset();
|
void reset();
|
||||||
void interpret_one();
|
void interpret_one();
|
||||||
void interpret();
|
void interpret();
|
||||||
|
|
||||||
|
inline bool interactionWait()
|
||||||
|
{
|
||||||
|
return pause.voice || pause.menu || pause.dissolve || pause.pause;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline bool dissolvePC()
|
||||||
|
{
|
||||||
|
return dissolveIndex < (uint32_t)script::dissolves_length && script::dissolves[dissolveIndex].first_statement == pc;
|
||||||
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|||||||
@ -48,7 +48,6 @@ namespace renpy::language {
|
|||||||
stop,
|
stop,
|
||||||
pause,
|
pause,
|
||||||
hide,
|
hide,
|
||||||
dissolve,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
struct jump {
|
struct jump {
|
||||||
@ -107,7 +106,9 @@ namespace renpy::language {
|
|||||||
};
|
};
|
||||||
|
|
||||||
struct dissolve {
|
struct dissolve {
|
||||||
float duration;
|
double duration;
|
||||||
|
uint32_t first_statement;
|
||||||
|
uint32_t count;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct statement {
|
struct statement {
|
||||||
@ -124,7 +125,6 @@ namespace renpy::language {
|
|||||||
renpy::language::stop stop;
|
renpy::language::stop stop;
|
||||||
renpy::language::pause pause;
|
renpy::language::pause pause;
|
||||||
renpy::language::hide hide;
|
renpy::language::hide hide;
|
||||||
renpy::language::dissolve dissolve;
|
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|||||||
@ -16,6 +16,9 @@ namespace renpy::script {
|
|||||||
extern const language::option options[];
|
extern const language::option options[];
|
||||||
extern const int options_length;
|
extern const int options_length;
|
||||||
|
|
||||||
|
extern const language::dissolve dissolves[];
|
||||||
|
extern const int dissolves_length;
|
||||||
|
|
||||||
extern const language::statement statements[];
|
extern const language::statement statements[];
|
||||||
extern const int statements_length;
|
extern const int statements_length;
|
||||||
|
|
||||||
|
|||||||
@ -80,11 +80,21 @@ namespace renpy {
|
|||||||
void load_images();
|
void load_images();
|
||||||
void create_pipeline();
|
void create_pipeline();
|
||||||
void create_instance_buffers();
|
void create_instance_buffers();
|
||||||
|
|
||||||
|
void draw_menu_frame(VkCommandBuffer commandBuffer,
|
||||||
|
uint32_t frameIndex,
|
||||||
|
renpy::interpreter const& state,
|
||||||
|
int & outputIndex,
|
||||||
|
int mx, int my) const;
|
||||||
|
void draw_say_frame(VkCommandBuffer commandBuffer,
|
||||||
|
uint32_t frameIndex,
|
||||||
|
renpy::interpreter const& state,
|
||||||
|
int & outputIndex) const;
|
||||||
void draw(VkCommandBuffer commandBuffer,
|
void draw(VkCommandBuffer commandBuffer,
|
||||||
uint32_t frameIndex,
|
uint32_t frameIndex,
|
||||||
renpy::interpreter const& state,
|
renpy::interpreter const& state,
|
||||||
int mx,
|
int mx, int my,
|
||||||
int my);
|
bool drawText) const;
|
||||||
|
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|||||||
@ -14,6 +14,7 @@ class State:
|
|||||||
statements: list
|
statements: list
|
||||||
menus: list
|
menus: list
|
||||||
entries: dict
|
entries: dict
|
||||||
|
dissolves: list
|
||||||
|
|
||||||
images_lookup: dict[str, int] # identifier to image index
|
images_lookup: dict[str, int] # identifier to image index
|
||||||
colors_lookup: dict[str, int] # identifier to image index
|
colors_lookup: dict[str, int] # identifier to image index
|
||||||
@ -35,6 +36,12 @@ class InternalMenu:
|
|||||||
class InternalJump:
|
class InternalJump:
|
||||||
target: tuple
|
target: tuple
|
||||||
|
|
||||||
|
@dataclass
|
||||||
|
class InternalDissolve:
|
||||||
|
duration: int
|
||||||
|
first_statement: int
|
||||||
|
count: int
|
||||||
|
|
||||||
def lhs_key(lhs):
|
def lhs_key(lhs):
|
||||||
return tuple(l.lexeme for l in lhs)
|
return tuple(l.lexeme for l in lhs)
|
||||||
|
|
||||||
@ -46,7 +53,6 @@ simple_statement_types = {
|
|||||||
parse.Scene,
|
parse.Scene,
|
||||||
parse.Show,
|
parse.Show,
|
||||||
parse.Voice,
|
parse.Voice,
|
||||||
parse.With,
|
|
||||||
parse.Stop,
|
parse.Stop,
|
||||||
parse.Pause,
|
parse.Pause,
|
||||||
parse.Hide,
|
parse.Hide,
|
||||||
@ -123,6 +129,34 @@ def pass1(state, ast):
|
|||||||
state.statements.append(InternalJump(menu_end_key))
|
state.statements.append(InternalJump(menu_end_key))
|
||||||
assert menu_end_key not in state.labels_lookup
|
assert menu_end_key not in state.labels_lookup
|
||||||
state.labels_lookup[menu_end_key] = len(state.statements)
|
state.labels_lookup[menu_end_key] = len(state.statements)
|
||||||
|
elif type(ast) is parse.With:
|
||||||
|
if ast.function_call.name.lexeme != b'Dissolve':
|
||||||
|
assert False, ast
|
||||||
|
duration, = ast.function_call.args
|
||||||
|
duration = duration.lexeme
|
||||||
|
|
||||||
|
scene_index = None
|
||||||
|
for i in reversed(range(len(state.statements))):
|
||||||
|
if type(state.statements[i]) is parse.Scene:
|
||||||
|
scene_index = i
|
||||||
|
break
|
||||||
|
for i in range(scene_index + 1, len(state.statements)):
|
||||||
|
ast = state.statements[i]
|
||||||
|
if type(ast) is parse.Voice:
|
||||||
|
assert False, ast
|
||||||
|
elif type(ast) is parse.Menu:
|
||||||
|
assert False, ast
|
||||||
|
elif type(ast) is parse.Pause:
|
||||||
|
assert False, ast
|
||||||
|
else:
|
||||||
|
assert type(ast) in simple_statement_types, ast
|
||||||
|
|
||||||
|
assert scene_index is not None
|
||||||
|
state.dissolves.append(InternalDissolve(
|
||||||
|
duration = duration,
|
||||||
|
first_statement = scene_index,
|
||||||
|
count = len(state.statements) - scene_index,
|
||||||
|
))
|
||||||
elif type(ast) in simple_statement_types:
|
elif type(ast) in simple_statement_types:
|
||||||
pass
|
pass
|
||||||
else:
|
else:
|
||||||
@ -161,13 +195,6 @@ def pass2_statement(state, pc, statement):
|
|||||||
color = parse_color(state.colors[color_index].path.lexeme)
|
color = parse_color(state.colors[color_index].path.lexeme)
|
||||||
comment = ".".join(k.decode('utf-8') for k in key)
|
comment = ".".join(k.decode('utf-8') for k in key)
|
||||||
yield f"{{ .type = type::scene_color, .scene_color = {{ .color = 0x{color:06x} }} }}, // {pc} {comment}"
|
yield f"{{ .type = type::scene_color, .scene_color = {{ .color = 0x{color:06x} }} }}, // {pc} {comment}"
|
||||||
elif type(statement) is parse.With:
|
|
||||||
#print(f"not implemented: {statement}", file=sys.stderr)
|
|
||||||
if statement.function_call.name.lexeme == b'Dissolve':
|
|
||||||
duration, = statement.function_call.args
|
|
||||||
yield f"{{ .type = type::dissolve, .dissolve = {{ .duration = {duration.lexeme} }} }}, // {pc}"
|
|
||||||
else:
|
|
||||||
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 = state.audio_lookup[statement.path.lexeme]
|
audio_index = state.audio_lookup[statement.path.lexeme]
|
||||||
@ -217,7 +244,6 @@ def pass2_statement(state, pc, statement):
|
|||||||
comment = ".".join(k.decode('utf-8') for k in key)
|
comment = ".".join(k.decode('utf-8') for k in key)
|
||||||
yield f"{{ .type = type::hide, .hide = {{ .imageIndex = {image_index} }} }}, // {pc} {comment}"
|
yield f"{{ .type = type::hide, .hide = {{ .imageIndex = {image_index} }} }}, // {pc} {comment}"
|
||||||
else:
|
else:
|
||||||
pass
|
|
||||||
assert False, (type(statement), statement)
|
assert False, (type(statement), statement)
|
||||||
|
|
||||||
def pass2_statements(state):
|
def pass2_statements(state):
|
||||||
@ -286,6 +312,13 @@ def pass2_options(state):
|
|||||||
yield "};"
|
yield "};"
|
||||||
yield "const int options_length = (sizeof (options)) / (sizeof (options[0]));"
|
yield "const int options_length = (sizeof (options)) / (sizeof (options[0]));"
|
||||||
|
|
||||||
|
def pass2_dissolves(state):
|
||||||
|
yield "const language::dissolve dissolves[] = {"
|
||||||
|
for dissolve in state.dissolves:
|
||||||
|
yield f"{{ .duration = {dissolve.duration}, .first_statement = {dissolve.first_statement}, .count = {dissolve.count} }},"
|
||||||
|
yield "};"
|
||||||
|
yield "const int dissolves_length = (sizeof (dissolves)) / (sizeof (dissolves[0]));"
|
||||||
|
|
||||||
def pass2(state):
|
def pass2(state):
|
||||||
yield "#include \"renpy/language.h\""
|
yield "#include \"renpy/language.h\""
|
||||||
yield "#include \"renpy/script.h\""
|
yield "#include \"renpy/script.h\""
|
||||||
@ -297,6 +330,7 @@ def pass2(state):
|
|||||||
yield from pass2_audio(state)
|
yield from pass2_audio(state)
|
||||||
yield from pass2_images(state)
|
yield from pass2_images(state)
|
||||||
yield from pass2_options(state)
|
yield from pass2_options(state)
|
||||||
|
yield from pass2_dissolves(state)
|
||||||
yield from pass2_statements(state)
|
yield from pass2_statements(state)
|
||||||
yield "}"
|
yield "}"
|
||||||
|
|
||||||
@ -315,6 +349,7 @@ image _internal_flowers = "flowers.png"
|
|||||||
statements = list(),
|
statements = list(),
|
||||||
menus = list(),
|
menus = list(),
|
||||||
entries = dict(),
|
entries = dict(),
|
||||||
|
dissolves = list(),
|
||||||
images_lookup = dict(),
|
images_lookup = dict(),
|
||||||
colors_lookup = dict(),
|
colors_lookup = dict(),
|
||||||
characters_lookup = dict(),
|
characters_lookup = dict(),
|
||||||
|
|||||||
@ -88,8 +88,8 @@ float4 PSMain(VSOutput input) : SV_TARGET
|
|||||||
if (color.w == 0.0)
|
if (color.w == 0.0)
|
||||||
discard;
|
discard;
|
||||||
|
|
||||||
float gamma = 2.2;
|
//float gamma = 2.2;
|
||||||
color.xyz = pow(color.xyz, float3(gamma.xxx));
|
//color.xyz = pow(color.xyz, float3(gamma.xxx));
|
||||||
|
|
||||||
return float4(color.xyzw);
|
return float4(color.xyzw);
|
||||||
}
|
}
|
||||||
|
|||||||
59
shader/renpy_composite.hlsl
Normal file
59
shader/renpy_composite.hlsl
Normal file
@ -0,0 +1,59 @@
|
|||||||
|
[[vk::binding(0, 0)]] SamplerState ClosestSampler;
|
||||||
|
[[vk::binding(1, 0)]] Texture2D Texture[];
|
||||||
|
|
||||||
|
struct PushConstant {
|
||||||
|
float DissolveLerp;
|
||||||
|
float TextLerp;
|
||||||
|
};
|
||||||
|
|
||||||
|
[[vk::push_constant]] PushConstant PushConstant;
|
||||||
|
|
||||||
|
struct VSInput
|
||||||
|
{
|
||||||
|
float2 Position : POSITION0;
|
||||||
|
float2 Texture : TEXCOORD0;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct VSOutput
|
||||||
|
{
|
||||||
|
float4 Position : SV_POSITION;
|
||||||
|
float2 Texture : NORMAL0;
|
||||||
|
float DissolveLerp : DissolveLerp;
|
||||||
|
float TextLerp : TextLerp;
|
||||||
|
};
|
||||||
|
|
||||||
|
float4 mix(float4 x, float4 y, float a)
|
||||||
|
{
|
||||||
|
return x * (1 - a) + y * a;
|
||||||
|
}
|
||||||
|
|
||||||
|
[shader("vertex")]
|
||||||
|
VSOutput VSMain(VSInput input)
|
||||||
|
{
|
||||||
|
VSOutput output = (VSOutput)0;
|
||||||
|
output.Position = float4(input.Position, 0, 1);
|
||||||
|
output.Texture = input.Texture;
|
||||||
|
output.DissolveLerp = PushConstant.DissolveLerp;
|
||||||
|
output.TextLerp = PushConstant.TextLerp;
|
||||||
|
|
||||||
|
return output;
|
||||||
|
}
|
||||||
|
|
||||||
|
[shader("pixel")]
|
||||||
|
float4 PSMain(VSOutput input) : SV_TARGET
|
||||||
|
{
|
||||||
|
float4 color0 = Texture[0].Sample(ClosestSampler, input.Texture);
|
||||||
|
|
||||||
|
float4 color = float4(0, 0, 0, 0);
|
||||||
|
if (input.DissolveLerp >= 0) {
|
||||||
|
float4 color1 = Texture[1].Sample(ClosestSampler, input.Texture);
|
||||||
|
float4 color01 = mix(color0, color1, input.TextLerp);
|
||||||
|
|
||||||
|
float4 color2 = Texture[2].Sample(ClosestSampler, input.Texture);
|
||||||
|
color = mix(color01, color2, input.DissolveLerp);
|
||||||
|
} else {
|
||||||
|
color = color0;
|
||||||
|
}
|
||||||
|
|
||||||
|
return float4(color.xyzw);
|
||||||
|
}
|
||||||
@ -622,7 +622,7 @@ namespace font::outline {
|
|||||||
int& outputIndex,
|
int& outputIndex,
|
||||||
int startIndex,
|
int startIndex,
|
||||||
int endIndex,
|
int endIndex,
|
||||||
uint32_t color)
|
uint32_t color) const
|
||||||
{
|
{
|
||||||
for (int i = startIndex; i < endIndex; i++) {
|
for (int i = startIndex; i < endIndex; i++) {
|
||||||
char c = string[i];
|
char c = string[i];
|
||||||
@ -645,7 +645,7 @@ namespace font::outline {
|
|||||||
uint32_t minX,
|
uint32_t minX,
|
||||||
uint32_t maxWidth,
|
uint32_t maxWidth,
|
||||||
int& outputIndex,
|
int& outputIndex,
|
||||||
uint32_t color)
|
uint32_t color) const
|
||||||
{
|
{
|
||||||
int stringIndex = 0;
|
int stringIndex = 0;
|
||||||
int lineStart = stringIndex;
|
int lineStart = stringIndex;
|
||||||
@ -700,7 +700,7 @@ namespace font::outline {
|
|||||||
|
|
||||||
void font::draw(VkCommandBuffer commandBuffer,
|
void font::draw(VkCommandBuffer commandBuffer,
|
||||||
uint32_t frameIndex,
|
uint32_t frameIndex,
|
||||||
renpy::interpreter const& state)
|
renpy::interpreter const& state) const
|
||||||
{
|
{
|
||||||
// transfer
|
// transfer
|
||||||
int outputIndex = 0;
|
int outputIndex = 0;
|
||||||
|
|||||||
287
src/main.cpp
287
src/main.cpp
@ -23,6 +23,7 @@
|
|||||||
|
|
||||||
#include "font/outline.h"
|
#include "font/outline.h"
|
||||||
#include "renpy/vulkan.h"
|
#include "renpy/vulkan.h"
|
||||||
|
#include "renpy/composite/vulkan.h"
|
||||||
#include "renpy/interpreter.h"
|
#include "renpy/interpreter.h"
|
||||||
#include "renpy/interact.h"
|
#include "renpy/interact.h"
|
||||||
#include "renpy/script.h"
|
#include "renpy/script.h"
|
||||||
@ -43,6 +44,11 @@ VkImage depthImage{ VK_NULL_HANDLE };
|
|||||||
VkImageView depthImageView{ VK_NULL_HANDLE };
|
VkImageView depthImageView{ VK_NULL_HANDLE };
|
||||||
VkDeviceMemory depthMemory{ VK_NULL_HANDLE };
|
VkDeviceMemory depthMemory{ VK_NULL_HANDLE };
|
||||||
|
|
||||||
|
constexpr int colorImageCount = 3;
|
||||||
|
VkImage colorImage[colorImageCount]{ VK_NULL_HANDLE, VK_NULL_HANDLE };
|
||||||
|
VkImageView colorImageView[colorImageCount]{ VK_NULL_HANDLE, VK_NULL_HANDLE };
|
||||||
|
VkDeviceMemory colorMemory[colorImageCount]{ VK_NULL_HANDLE, VK_NULL_HANDLE };
|
||||||
|
|
||||||
uint32_t shadowArrayLayers{ 6 };
|
uint32_t shadowArrayLayers{ 6 };
|
||||||
VkImage shadowDepthImage{ VK_NULL_HANDLE };
|
VkImage shadowDepthImage{ VK_NULL_HANDLE };
|
||||||
VkImageView shadowDepthImageView{ VK_NULL_HANDLE };
|
VkImageView shadowDepthImageView{ VK_NULL_HANDLE };
|
||||||
@ -114,6 +120,7 @@ void createDepth(VkDeviceSize nonCoherentAtomSize,
|
|||||||
uint32_t height,
|
uint32_t height,
|
||||||
VkFormat format,
|
VkFormat format,
|
||||||
VkImageUsageFlags usage,
|
VkImageUsageFlags usage,
|
||||||
|
VkImageAspectFlags aspect,
|
||||||
uint32_t arrayLayers,
|
uint32_t arrayLayers,
|
||||||
VkImage * image,
|
VkImage * image,
|
||||||
VkDeviceMemory * memory,
|
VkDeviceMemory * memory,
|
||||||
@ -160,7 +167,7 @@ void createDepth(VkDeviceSize nonCoherentAtomSize,
|
|||||||
.viewType = viewType,
|
.viewType = viewType,
|
||||||
.format = format,
|
.format = format,
|
||||||
.subresourceRange{
|
.subresourceRange{
|
||||||
.aspectMask = VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT,
|
.aspectMask = aspect,
|
||||||
.levelCount = 1,
|
.levelCount = 1,
|
||||||
.layerCount = arrayLayers
|
.layerCount = arrayLayers
|
||||||
}
|
}
|
||||||
@ -275,6 +282,7 @@ void recreateSwapchain(VkSurfaceFormatKHR surfaceFormat,
|
|||||||
imageExtent.height,
|
imageExtent.height,
|
||||||
depthFormat,
|
depthFormat,
|
||||||
VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT,
|
VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT,
|
||||||
|
VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT,
|
||||||
arrayLayers,
|
arrayLayers,
|
||||||
&depthImage,
|
&depthImage,
|
||||||
&depthMemory,
|
&depthMemory,
|
||||||
@ -356,6 +364,151 @@ void gamepad_update(view & viewState)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void offscreenRender(VkCommandBuffer commandBuffer, int frameIndex,
|
||||||
|
int mx, int my, int colorIndex, bool drawText,
|
||||||
|
renpy::vulkan const & renpy_state,
|
||||||
|
renpy::interpreter const & interpreter_state,
|
||||||
|
font::outline::font const & font_state)
|
||||||
|
{
|
||||||
|
// barrier
|
||||||
|
constexpr int colorBarriersCount = 2;
|
||||||
|
VkImageMemoryBarrier2 colorBarriers[colorBarriersCount]{
|
||||||
|
{
|
||||||
|
.sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER_2,
|
||||||
|
.srcStageMask = VK_PIPELINE_STAGE_2_COLOR_ATTACHMENT_OUTPUT_BIT,
|
||||||
|
.srcAccessMask = 0,
|
||||||
|
.dstStageMask = VK_PIPELINE_STAGE_2_COLOR_ATTACHMENT_OUTPUT_BIT,
|
||||||
|
.dstAccessMask = VK_ACCESS_COLOR_ATTACHMENT_READ_BIT | VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,
|
||||||
|
.oldLayout = VK_IMAGE_LAYOUT_UNDEFINED,
|
||||||
|
.newLayout = VK_IMAGE_LAYOUT_ATTACHMENT_OPTIMAL,
|
||||||
|
.image = colorImage[colorIndex],
|
||||||
|
.subresourceRange{
|
||||||
|
.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT,
|
||||||
|
.levelCount = 1,
|
||||||
|
.layerCount = 1
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
.sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER_2,
|
||||||
|
.srcStageMask = VK_PIPELINE_STAGE_2_EARLY_FRAGMENT_TESTS_BIT | VK_PIPELINE_STAGE_2_LATE_FRAGMENT_TESTS_BIT,
|
||||||
|
.srcAccessMask = VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT,
|
||||||
|
.dstStageMask = VK_PIPELINE_STAGE_2_EARLY_FRAGMENT_TESTS_BIT | VK_PIPELINE_STAGE_2_LATE_FRAGMENT_TESTS_BIT,
|
||||||
|
.dstAccessMask = VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT,
|
||||||
|
.oldLayout = VK_IMAGE_LAYOUT_UNDEFINED,
|
||||||
|
.newLayout = VK_IMAGE_LAYOUT_ATTACHMENT_OPTIMAL,
|
||||||
|
.image = depthImage,
|
||||||
|
.subresourceRange{
|
||||||
|
.aspectMask = VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT,
|
||||||
|
.levelCount = 1,
|
||||||
|
.layerCount = 1
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
VkDependencyInfo colorBarrierDependencyInfo{
|
||||||
|
.sType = VK_STRUCTURE_TYPE_DEPENDENCY_INFO,
|
||||||
|
.imageMemoryBarrierCount = colorBarriersCount,
|
||||||
|
.pImageMemoryBarriers = colorBarriers
|
||||||
|
};
|
||||||
|
vkCmdPipelineBarrier2(commandBuffer, &colorBarrierDependencyInfo);
|
||||||
|
|
||||||
|
// attachments
|
||||||
|
|
||||||
|
VkRenderingAttachmentInfo colorRenderingAttachmentInfo{
|
||||||
|
.sType = VK_STRUCTURE_TYPE_RENDERING_ATTACHMENT_INFO,
|
||||||
|
.imageView = colorImageView[colorIndex],
|
||||||
|
.imageLayout = VK_IMAGE_LAYOUT_ATTACHMENT_OPTIMAL,
|
||||||
|
.loadOp = VK_ATTACHMENT_LOAD_OP_CLEAR,
|
||||||
|
.storeOp = VK_ATTACHMENT_STORE_OP_STORE,
|
||||||
|
.clearValue{ .color{ { 0.0f, 0.0f, 0.0f, 0.0f} } }
|
||||||
|
};
|
||||||
|
VkRenderingAttachmentInfo depthRenderingAttachmentInfo{
|
||||||
|
.sType = VK_STRUCTURE_TYPE_RENDERING_ATTACHMENT_INFO,
|
||||||
|
.imageView = depthImageView,
|
||||||
|
.imageLayout = VK_IMAGE_LAYOUT_ATTACHMENT_OPTIMAL,
|
||||||
|
.loadOp = VK_ATTACHMENT_LOAD_OP_CLEAR,
|
||||||
|
.storeOp = VK_ATTACHMENT_STORE_OP_DONT_CARE,
|
||||||
|
.clearValue{ .depthStencil{ 1.0f, 0 } }
|
||||||
|
};
|
||||||
|
|
||||||
|
VkRenderingInfo colorRenderingInfo{
|
||||||
|
.sType = VK_STRUCTURE_TYPE_RENDERING_INFO,
|
||||||
|
.renderArea{ .extent{ .width = 1280, .height = 720 } },
|
||||||
|
.layerCount = 1,
|
||||||
|
.colorAttachmentCount = 1,
|
||||||
|
.pColorAttachments = &colorRenderingAttachmentInfo,
|
||||||
|
.pDepthAttachment = &depthRenderingAttachmentInfo,
|
||||||
|
.pStencilAttachment = &depthRenderingAttachmentInfo,
|
||||||
|
};
|
||||||
|
vkCmdBeginRendering(commandBuffer, &colorRenderingInfo);
|
||||||
|
|
||||||
|
// viewport/scissor
|
||||||
|
|
||||||
|
VkViewport shadowViewport{
|
||||||
|
.x = 0,
|
||||||
|
.y = 0,
|
||||||
|
.width = static_cast<float>(windowSize.x),
|
||||||
|
.height = static_cast<float>(windowSize.y),
|
||||||
|
.minDepth = 0.0f,
|
||||||
|
.maxDepth = 1.0f
|
||||||
|
};
|
||||||
|
vkCmdSetViewport(commandBuffer, 0, 1, &shadowViewport);
|
||||||
|
VkRect2D shadowScissor{
|
||||||
|
.extent{
|
||||||
|
.width = (uint32_t)windowSize.x,
|
||||||
|
.height = (uint32_t)windowSize.y
|
||||||
|
}
|
||||||
|
};
|
||||||
|
vkCmdSetScissor(commandBuffer, 0, 1, &shadowScissor);
|
||||||
|
|
||||||
|
// draw
|
||||||
|
|
||||||
|
//collada_state.vulkan.excludeMaterialIndex = lightMaterialIndex;
|
||||||
|
//collada_state.vulkan.pipelineIndex = 0; // shadow pipeline
|
||||||
|
//collada_state.draw();
|
||||||
|
|
||||||
|
renpy_state.draw(commandBuffer, frameIndex, interpreter_state, mx, my, drawText);
|
||||||
|
if (drawText) {
|
||||||
|
font_state.draw(commandBuffer, frameIndex, interpreter_state);
|
||||||
|
}
|
||||||
|
|
||||||
|
vkCmdEndRendering(commandBuffer);
|
||||||
|
|
||||||
|
// barrier
|
||||||
|
|
||||||
|
{
|
||||||
|
VkImageMemoryBarrier2 colorBarriers[1]{
|
||||||
|
{
|
||||||
|
.sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER_2,
|
||||||
|
.srcStageMask = VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT,
|
||||||
|
.srcAccessMask = VK_ACCESS_MEMORY_READ_BIT,
|
||||||
|
.dstStageMask = VK_PIPELINE_STAGE_2_FRAGMENT_SHADER_BIT,
|
||||||
|
.dstAccessMask = VK_ACCESS_2_INPUT_ATTACHMENT_READ_BIT,
|
||||||
|
.oldLayout = VK_IMAGE_LAYOUT_ATTACHMENT_OPTIMAL,
|
||||||
|
.newLayout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL,
|
||||||
|
.image = colorImage[frameIndex],
|
||||||
|
.subresourceRange{
|
||||||
|
.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT,
|
||||||
|
.levelCount = 1,
|
||||||
|
.layerCount = 1,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
VkDependencyInfo colorBarrierDependencyInfo{
|
||||||
|
.sType = VK_STRUCTURE_TYPE_DEPENDENCY_INFO,
|
||||||
|
.imageMemoryBarrierCount = 1,
|
||||||
|
.pImageMemoryBarriers = colorBarriers
|
||||||
|
};
|
||||||
|
vkCmdPipelineBarrier2(commandBuffer, &colorBarrierDependencyInfo);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline double clamp01(double a)
|
||||||
|
{
|
||||||
|
if (a < 0.0) return 0.0;
|
||||||
|
if (a > 1.0) return 1.0;
|
||||||
|
return a;
|
||||||
|
}
|
||||||
|
|
||||||
int main()
|
int main()
|
||||||
{
|
{
|
||||||
file::init();
|
file::init();
|
||||||
@ -530,6 +683,16 @@ int main()
|
|||||||
VK_CHECK(vkGetPhysicalDeviceSurfaceFormatsKHR(physicalDevice, surface, &surfaceFormatCount, surfaceFormats));
|
VK_CHECK(vkGetPhysicalDeviceSurfaceFormatsKHR(physicalDevice, surface, &surfaceFormatCount, surfaceFormats));
|
||||||
uint32_t surfaceFormatIndex{ 0 };
|
uint32_t surfaceFormatIndex{ 0 };
|
||||||
printf("surfaceFormatCount %d\n", surfaceFormatCount);
|
printf("surfaceFormatCount %d\n", surfaceFormatCount);
|
||||||
|
for (uint32_t i = 0; i < surfaceFormatCount; i++) {
|
||||||
|
if (surfaceFormats[i].format == VK_FORMAT_B8G8R8A8_UNORM) {
|
||||||
|
surfaceFormatIndex = i;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (surfaceFormats[i].format == VK_FORMAT_R8G8B8A8_UNORM) {
|
||||||
|
surfaceFormatIndex = i;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
for (uint32_t i = 0; i < surfaceFormatCount; i++) {
|
for (uint32_t i = 0; i < surfaceFormatCount; i++) {
|
||||||
printf("surfaceFormat[%d] %s %s%s\n", i, string_VkFormat(surfaceFormats[i].format), string_VkColorSpaceKHR(surfaceFormats[i].colorSpace), (i == surfaceFormatIndex) ? " [selected]" : "");
|
printf("surfaceFormat[%d] %s %s%s\n", i, string_VkFormat(surfaceFormats[i].format), string_VkColorSpaceKHR(surfaceFormats[i].colorSpace), (i == surfaceFormatIndex) ? " [selected]" : "");
|
||||||
}
|
}
|
||||||
@ -564,6 +727,7 @@ int main()
|
|||||||
720,
|
720,
|
||||||
depthFormat,
|
depthFormat,
|
||||||
VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT | VK_IMAGE_USAGE_SAMPLED_BIT,
|
VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT | VK_IMAGE_USAGE_SAMPLED_BIT,
|
||||||
|
VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT,
|
||||||
shadowArrayLayers,
|
shadowArrayLayers,
|
||||||
&shadowDepthImage,
|
&shadowDepthImage,
|
||||||
&shadowDepthMemory,
|
&shadowDepthMemory,
|
||||||
@ -656,6 +820,25 @@ int main()
|
|||||||
};
|
};
|
||||||
VK_CHECK(vkCreateSampler(device, &samplerCreateInfo2, nullptr, &textureSamplers[2]));
|
VK_CHECK(vkCreateSampler(device, &samplerCreateInfo2, nullptr, &textureSamplers[2]));
|
||||||
|
|
||||||
|
//////////////////////////////////////////////////////////////////////
|
||||||
|
// off-screen color buffers
|
||||||
|
//////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
for (int i = 0; i < colorImageCount; i++) {
|
||||||
|
uint32_t arrayLayers{ 1 };
|
||||||
|
createDepth(physicalDeviceProperties.limits.nonCoherentAtomSize,
|
||||||
|
physicalDeviceMemoryProperties,
|
||||||
|
1280,
|
||||||
|
720,
|
||||||
|
surfaceFormat.format,
|
||||||
|
VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_SAMPLED_BIT,
|
||||||
|
VK_IMAGE_ASPECT_COLOR_BIT,
|
||||||
|
arrayLayers,
|
||||||
|
&colorImage[i],
|
||||||
|
&colorMemory[i],
|
||||||
|
&colorImageView[i]);
|
||||||
|
}
|
||||||
|
|
||||||
//////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////
|
||||||
// initialize collada
|
// initialize collada
|
||||||
//////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////
|
||||||
@ -736,6 +919,23 @@ int main()
|
|||||||
renpy::interpreter interpreter_state;
|
renpy::interpreter interpreter_state;
|
||||||
interpreter_state.reset();
|
interpreter_state.reset();
|
||||||
|
|
||||||
|
//////////////////////////////////////////////////////////////////////
|
||||||
|
// renpy composite
|
||||||
|
//////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
renpy::composite::vulkan composite_state;
|
||||||
|
composite_state.initial_state(instance,
|
||||||
|
device,
|
||||||
|
queue,
|
||||||
|
commandPool,
|
||||||
|
physicalDeviceProperties,
|
||||||
|
physicalDeviceMemoryProperties,
|
||||||
|
surfaceFormat.format,
|
||||||
|
depthFormat,
|
||||||
|
textureSamplers[2]);
|
||||||
|
composite_state.init();
|
||||||
|
composite_state.write_descriptor_sets(colorImageView, colorImageCount);
|
||||||
|
|
||||||
//////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////
|
||||||
// initialize view
|
// initialize view
|
||||||
//////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////
|
||||||
@ -775,6 +975,9 @@ int main()
|
|||||||
int64_t start_time;
|
int64_t start_time;
|
||||||
SDL_GetCurrentTime(&start_time);
|
SDL_GetCurrentTime(&start_time);
|
||||||
|
|
||||||
|
double pause_start = 0.0;
|
||||||
|
double dissolve_start = 0.0;
|
||||||
|
|
||||||
//collada_state.update(0);
|
//collada_state.update(0);
|
||||||
|
|
||||||
audio::init();
|
audio::init();
|
||||||
@ -782,8 +985,39 @@ int main()
|
|||||||
|
|
||||||
while (quit == false) {
|
while (quit == false) {
|
||||||
audio::update();
|
audio::update();
|
||||||
|
|
||||||
|
//////////////////////////////////////////////////////////////////////
|
||||||
|
// interpreter update
|
||||||
|
//////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
interpreter_state.interpret();
|
interpreter_state.interpret();
|
||||||
|
|
||||||
|
if (interpreter_state.pause.pause) {
|
||||||
|
if (pause_start == 0.0) {
|
||||||
|
fprintf(stderr, "pause %f\n", interpreter_state.pauseDuration);
|
||||||
|
pause_start = getTime(start_time);
|
||||||
|
} else if (getTime(start_time) - pause_start >= interpreter_state.pauseDuration) {
|
||||||
|
fprintf(stderr, "unpause %f\n", interpreter_state.pauseDuration);
|
||||||
|
pause_start = 0.0;
|
||||||
|
interpreter_state.pause.pause = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (interpreter_state.pause.dissolve) {
|
||||||
|
if (dissolve_start == 0.0) {
|
||||||
|
fprintf(stderr, "dissolve %f\n", interpreter_state.dissolveDuration);
|
||||||
|
dissolve_start = getTime(start_time);
|
||||||
|
} else if (getTime(start_time) - dissolve_start >= interpreter_state.dissolveDuration) {
|
||||||
|
fprintf(stderr, "undissolve %f\n", interpreter_state.dissolveDuration);
|
||||||
|
dissolve_start = 0.0;
|
||||||
|
interpreter_state.pause.dissolve = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//////////////////////////////////////////////////////////////////////
|
||||||
|
// sdl
|
||||||
|
//////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
SDL_Event event;
|
SDL_Event event;
|
||||||
while (SDL_PollEvent(&event)) {
|
while (SDL_PollEvent(&event)) {
|
||||||
if (event.type == SDL_EVENT_QUIT) {
|
if (event.type == SDL_EVENT_QUIT) {
|
||||||
@ -827,6 +1061,16 @@ int main()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//////////////////////////////////////////////////////////////////////
|
||||||
|
// renpy update
|
||||||
|
//////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
float mx;
|
||||||
|
float my;
|
||||||
|
uint32_t mouseFlags = SDL_GetMouseState(&mx, &my);
|
||||||
|
bool mLeft = (mouseFlags & SDL_BUTTON_LMASK) != 0;
|
||||||
|
renpy::update(interpreter_state, mx, my, mLeft);
|
||||||
|
|
||||||
//////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////
|
||||||
// gamepad update
|
// gamepad update
|
||||||
//////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////
|
||||||
@ -902,6 +1146,7 @@ int main()
|
|||||||
// shadow render
|
// shadow render
|
||||||
//////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
/*
|
||||||
// barrier
|
// barrier
|
||||||
VkImageMemoryBarrier2 shadowBarriers[1]{
|
VkImageMemoryBarrier2 shadowBarriers[1]{
|
||||||
VkImageMemoryBarrier2{
|
VkImageMemoryBarrier2{
|
||||||
@ -1002,6 +1247,19 @@ int main()
|
|||||||
};
|
};
|
||||||
vkCmdPipelineBarrier2(commandBuffer, &shadowBarrierDependencyInfo);
|
vkCmdPipelineBarrier2(commandBuffer, &shadowBarrierDependencyInfo);
|
||||||
}
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
//////////////////////////////////////////////////////////////////////
|
||||||
|
// offscreen render
|
||||||
|
//////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
if (interpreter_state.pause.dissolve) {
|
||||||
|
offscreenRender(commandBuffer, frameIndex, mx, my, 2, true, renpy_state, interpreter_state, font_state);
|
||||||
|
} else {
|
||||||
|
offscreenRender(commandBuffer, frameIndex, mx, my, 0, true, renpy_state, interpreter_state, font_state);
|
||||||
|
offscreenRender(commandBuffer, frameIndex, mx, my, 1, false, renpy_state, interpreter_state, font_state);
|
||||||
|
}
|
||||||
|
|
||||||
//////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////
|
||||||
// render
|
// render
|
||||||
@ -1086,7 +1344,12 @@ int main()
|
|||||||
.maxDepth = 1.0f
|
.maxDepth = 1.0f
|
||||||
};
|
};
|
||||||
vkCmdSetViewport(commandBuffer, 0, 1, &viewport);
|
vkCmdSetViewport(commandBuffer, 0, 1, &viewport);
|
||||||
VkRect2D scissor{ .extent{ .width = (uint32_t)windowSize.x, .height = (uint32_t)windowSize.y } };
|
VkRect2D scissor{
|
||||||
|
.extent{
|
||||||
|
.width = (uint32_t)windowSize.x,
|
||||||
|
.height = (uint32_t)windowSize.y
|
||||||
|
}
|
||||||
|
};
|
||||||
vkCmdSetScissor(commandBuffer, 0, 1, &scissor);
|
vkCmdSetScissor(commandBuffer, 0, 1, &scissor);
|
||||||
|
|
||||||
// draw
|
// draw
|
||||||
@ -1099,13 +1362,19 @@ int main()
|
|||||||
|
|
||||||
//minecraft_state.draw(commandBuffer, frameIndex);
|
//minecraft_state.draw(commandBuffer, frameIndex);
|
||||||
|
|
||||||
float mx;
|
//renpy_state.draw(commandBuffer, frameIndex, interpreter_state, mx, my);
|
||||||
float my;
|
//font_state.draw(commandBuffer, frameIndex, interpreter_state);
|
||||||
uint32_t mouseFlags = SDL_GetMouseState(&mx, &my);
|
|
||||||
bool mLeft = (mouseFlags & SDL_BUTTON_LMASK) != 0;
|
float dissolve_lerp = -1.0;
|
||||||
renpy::update(interpreter_state, mx, my, mLeft);
|
float text_lerp = -1.0;
|
||||||
renpy_state.draw(commandBuffer, frameIndex, interpreter_state, mx, my);
|
constexpr double textDissolveDuration = 0.3;
|
||||||
font_state.draw(commandBuffer, frameIndex, interpreter_state);
|
if (interpreter_state.pause.dissolve) {
|
||||||
|
double delta = getTime(start_time) - dissolve_start;
|
||||||
|
assert(interpreter_state.dissolveDuration > 0.0000001);
|
||||||
|
dissolve_lerp = clamp01(delta / interpreter_state.dissolveDuration);
|
||||||
|
text_lerp = clamp01(delta / textDissolveDuration);
|
||||||
|
}
|
||||||
|
composite_state.draw(commandBuffer, frameIndex, dissolve_lerp, text_lerp);
|
||||||
|
|
||||||
vkCmdEndRendering(commandBuffer);
|
vkCmdEndRendering(commandBuffer);
|
||||||
|
|
||||||
|
|||||||
414
src/renpy/composite/vulkan.cpp
Normal file
414
src/renpy/composite/vulkan.cpp
Normal file
@ -0,0 +1,414 @@
|
|||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
#ifdef __APPLE__
|
||||||
|
#include "vulkan/vulkan.h"
|
||||||
|
#else
|
||||||
|
#include "volk/volk.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include "vulkan/vk_enum_string_helper.h"
|
||||||
|
#include "vulkan_helper.h"
|
||||||
|
#include "check.h"
|
||||||
|
#include "new.h"
|
||||||
|
#include "file.h"
|
||||||
|
|
||||||
|
#include "renpy/composite/vulkan.h"
|
||||||
|
|
||||||
|
namespace renpy::composite {
|
||||||
|
static constexpr int imageCount = 3;
|
||||||
|
|
||||||
|
static const _Float16 vertexData[] = {
|
||||||
|
// x y u v
|
||||||
|
(_Float16)-1.0, (_Float16)-1.0, (_Float16)0.0, (_Float16)0.0,
|
||||||
|
(_Float16)1.0, (_Float16)-1.0, (_Float16)1.0, (_Float16)0.0,
|
||||||
|
(_Float16)-1.0, (_Float16)1.0, (_Float16)0.0, (_Float16)1.0,
|
||||||
|
(_Float16)1.0, (_Float16)1.0, (_Float16)1.0, (_Float16)1.0,
|
||||||
|
};
|
||||||
|
static const uint32_t vertexSize = (sizeof (vertexData));
|
||||||
|
|
||||||
|
static const uint16_t indexData[] = {
|
||||||
|
0, 1, 2, 3,
|
||||||
|
};
|
||||||
|
static const uint32_t indexSize = (sizeof (indexData));
|
||||||
|
|
||||||
|
void vulkan::initial_state(VkInstance instance,
|
||||||
|
VkDevice device,
|
||||||
|
VkQueue queue,
|
||||||
|
VkCommandPool commandPool,
|
||||||
|
VkPhysicalDeviceProperties physicalDeviceProperties,
|
||||||
|
VkPhysicalDeviceMemoryProperties physicalDeviceMemoryProperties,
|
||||||
|
VkFormat colorFormat,
|
||||||
|
VkFormat depthFormat,
|
||||||
|
VkSampler linearSampler)
|
||||||
|
{
|
||||||
|
this->instance = instance;
|
||||||
|
this->device = device;
|
||||||
|
this->queue = queue;
|
||||||
|
this->commandPool = commandPool;
|
||||||
|
|
||||||
|
this->physicalDeviceProperties = physicalDeviceProperties;
|
||||||
|
this->physicalDeviceMemoryProperties = physicalDeviceMemoryProperties;
|
||||||
|
|
||||||
|
this->colorFormat = colorFormat;
|
||||||
|
this->depthFormat = depthFormat;
|
||||||
|
|
||||||
|
this->linearSampler = linearSampler;
|
||||||
|
}
|
||||||
|
|
||||||
|
void vulkan::init()
|
||||||
|
{
|
||||||
|
load_vertex_index_buffer();
|
||||||
|
load_shader();
|
||||||
|
create_descriptor_sets();
|
||||||
|
create_pipeline();
|
||||||
|
}
|
||||||
|
|
||||||
|
//////////////////////////////////////////////////////////////////////
|
||||||
|
// vertex index buffer
|
||||||
|
//////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
void vulkan::load_vertex_index_buffer()
|
||||||
|
{
|
||||||
|
void const * vertexStart = (void const *)vertexData;
|
||||||
|
void const * indexStart = (void const *)indexData;
|
||||||
|
|
||||||
|
vertexIndex = createVertexIndexBuffer(device,
|
||||||
|
physicalDeviceProperties,
|
||||||
|
physicalDeviceMemoryProperties,
|
||||||
|
vertexStart, vertexSize,
|
||||||
|
indexStart, indexSize);
|
||||||
|
}
|
||||||
|
|
||||||
|
//////////////////////////////////////////////////////////////////////
|
||||||
|
// shader
|
||||||
|
//////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
void vulkan::load_shader()
|
||||||
|
{
|
||||||
|
uint32_t shaderSize;
|
||||||
|
void const * shaderStart = file::open("shader/renpy_composite.spv", &shaderSize);
|
||||||
|
|
||||||
|
VkShaderModuleCreateInfo shaderModuleCreateInfo{
|
||||||
|
.sType = VK_STRUCTURE_TYPE_SHADER_MODULE_CREATE_INFO,
|
||||||
|
.codeSize = shaderSize,
|
||||||
|
.pCode = (uint32_t *)shaderStart
|
||||||
|
};
|
||||||
|
VK_CHECK(vkCreateShaderModule(device, &shaderModuleCreateInfo, nullptr, &shaderModule));
|
||||||
|
}
|
||||||
|
|
||||||
|
//////////////////////////////////////////////////////////////////////
|
||||||
|
// descriptor sets
|
||||||
|
//////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
void vulkan::create_descriptor_sets()
|
||||||
|
{
|
||||||
|
//
|
||||||
|
// pool
|
||||||
|
//
|
||||||
|
constexpr int descriptorPoolSizesCount = 2;
|
||||||
|
VkDescriptorPoolSize descriptorPoolSizes[descriptorPoolSizesCount]{
|
||||||
|
{ // linear sampler
|
||||||
|
.type = VK_DESCRIPTOR_TYPE_SAMPLER,
|
||||||
|
.descriptorCount = 1,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
.type = VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE,
|
||||||
|
.descriptorCount = imageCount,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
VkDescriptorPoolCreateInfo descriptorPoolCreateInfo{
|
||||||
|
.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO,
|
||||||
|
.maxSets = 1,
|
||||||
|
.poolSizeCount = descriptorPoolSizesCount,
|
||||||
|
.pPoolSizes = descriptorPoolSizes
|
||||||
|
};
|
||||||
|
VK_CHECK(vkCreateDescriptorPool(device, &descriptorPoolCreateInfo, nullptr, &descriptorPool));
|
||||||
|
|
||||||
|
//
|
||||||
|
// (set 0, constant)
|
||||||
|
//
|
||||||
|
{
|
||||||
|
constexpr int bindingCount = 2;
|
||||||
|
VkDescriptorSetLayoutBinding descriptorSetLayoutBindings[bindingCount]{
|
||||||
|
{
|
||||||
|
.binding = 0,
|
||||||
|
.descriptorType = VK_DESCRIPTOR_TYPE_SAMPLER,
|
||||||
|
.descriptorCount = 1,
|
||||||
|
.stageFlags = VK_SHADER_STAGE_FRAGMENT_BIT
|
||||||
|
},
|
||||||
|
{ // font image
|
||||||
|
.binding = 1,
|
||||||
|
.descriptorType = VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE,
|
||||||
|
.descriptorCount = imageCount,
|
||||||
|
.stageFlags = VK_SHADER_STAGE_FRAGMENT_BIT
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
VkDescriptorSetLayoutCreateInfo descriptorSetLayoutCreateInfo{
|
||||||
|
.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO,
|
||||||
|
.bindingCount = bindingCount,
|
||||||
|
.pBindings = descriptorSetLayoutBindings
|
||||||
|
};
|
||||||
|
VK_CHECK(vkCreateDescriptorSetLayout(device, &descriptorSetLayoutCreateInfo, nullptr, &descriptorSetLayouts[0]));
|
||||||
|
|
||||||
|
VkDescriptorSetAllocateInfo descriptorSetAllocateInfo{
|
||||||
|
.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO,
|
||||||
|
.descriptorPool = descriptorPool,
|
||||||
|
.descriptorSetCount = 1,
|
||||||
|
.pSetLayouts = &descriptorSetLayouts[0]
|
||||||
|
};
|
||||||
|
VK_CHECK(vkAllocateDescriptorSets(device, &descriptorSetAllocateInfo, &descriptorSet0));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//////////////////////////////////////////////////////////////////////
|
||||||
|
// descriptor set writes
|
||||||
|
//////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
void vulkan::write_descriptor_sets(VkImageView * imageViews, int imageViewCount)
|
||||||
|
{
|
||||||
|
assert(imageViewCount == imageCount);
|
||||||
|
constexpr uint32_t writeCount = 2;
|
||||||
|
VkWriteDescriptorSet writeDescriptorSets[writeCount];
|
||||||
|
uint32_t writeIndex = 0;
|
||||||
|
|
||||||
|
// set0 bindings
|
||||||
|
VkDescriptorImageInfo samplerDescriptorImageInfo = {
|
||||||
|
.sampler = linearSampler,
|
||||||
|
};
|
||||||
|
writeDescriptorSets[writeIndex++] = {
|
||||||
|
.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET,
|
||||||
|
.dstSet = descriptorSet0,
|
||||||
|
.dstBinding = 0,
|
||||||
|
.descriptorCount = 1,
|
||||||
|
.descriptorType = VK_DESCRIPTOR_TYPE_SAMPLER,
|
||||||
|
.pImageInfo = &samplerDescriptorImageInfo
|
||||||
|
};
|
||||||
|
|
||||||
|
VkDescriptorImageInfo sceneDescriptorImageInfos[imageCount];
|
||||||
|
for (int i = 0; i < imageCount; i++) {
|
||||||
|
sceneDescriptorImageInfos[i] = {
|
||||||
|
.imageView = imageViews[i],
|
||||||
|
.imageLayout = VK_IMAGE_LAYOUT_READ_ONLY_OPTIMAL
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
writeDescriptorSets[writeIndex++] = {
|
||||||
|
.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET,
|
||||||
|
.dstSet = descriptorSet0,
|
||||||
|
.dstBinding = 1,
|
||||||
|
.descriptorCount = imageCount,
|
||||||
|
.descriptorType = VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE,
|
||||||
|
.pImageInfo = sceneDescriptorImageInfos
|
||||||
|
};
|
||||||
|
|
||||||
|
assert(writeIndex == writeCount);
|
||||||
|
vkUpdateDescriptorSets(device, writeIndex, writeDescriptorSets, 0, nullptr);
|
||||||
|
//free(sceneDescriptorImageInfos);
|
||||||
|
}
|
||||||
|
|
||||||
|
//////////////////////////////////////////////////////////////////////
|
||||||
|
// pipeline
|
||||||
|
//////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
void vulkan::create_pipeline()
|
||||||
|
{
|
||||||
|
VkPushConstantRange pushConstantRange{
|
||||||
|
.stageFlags = VK_SHADER_STAGE_VERTEX_BIT,
|
||||||
|
.size = (sizeof (float)),
|
||||||
|
};
|
||||||
|
|
||||||
|
VkPipelineLayoutCreateInfo pipelineLayoutCreateInfo{
|
||||||
|
.sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO,
|
||||||
|
.setLayoutCount = descriptorSetLayoutCount,
|
||||||
|
.pSetLayouts = descriptorSetLayouts,
|
||||||
|
.pushConstantRangeCount = 1,
|
||||||
|
.pPushConstantRanges = &pushConstantRange,
|
||||||
|
};
|
||||||
|
VK_CHECK(vkCreatePipelineLayout(device, &pipelineLayoutCreateInfo, nullptr, &pipelineLayout));
|
||||||
|
|
||||||
|
VkPipelineInputAssemblyStateCreateInfo inputAssemblyState{
|
||||||
|
.sType = VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO,
|
||||||
|
.topology = VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP
|
||||||
|
};
|
||||||
|
|
||||||
|
VkPipelineShaderStageCreateInfo shaderStages[2]{
|
||||||
|
{
|
||||||
|
.sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO,
|
||||||
|
.stage = VK_SHADER_STAGE_VERTEX_BIT,
|
||||||
|
.module = shaderModule,
|
||||||
|
.pName = "VSMain"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
.sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO,
|
||||||
|
.stage = VK_SHADER_STAGE_FRAGMENT_BIT,
|
||||||
|
.module = shaderModule,
|
||||||
|
.pName = "PSMain"
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
VkPipelineViewportStateCreateInfo viewportState{
|
||||||
|
.sType = VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_STATE_CREATE_INFO,
|
||||||
|
.viewportCount = 1,
|
||||||
|
.scissorCount = 1
|
||||||
|
};
|
||||||
|
|
||||||
|
constexpr uint32_t dynamicStateCount = 2;
|
||||||
|
VkDynamicState dynamicStates[dynamicStateCount]{
|
||||||
|
VK_DYNAMIC_STATE_VIEWPORT,
|
||||||
|
VK_DYNAMIC_STATE_SCISSOR,
|
||||||
|
};
|
||||||
|
VkPipelineDynamicStateCreateInfo dynamicState{
|
||||||
|
.sType = VK_STRUCTURE_TYPE_PIPELINE_DYNAMIC_STATE_CREATE_INFO,
|
||||||
|
.dynamicStateCount = dynamicStateCount,
|
||||||
|
.pDynamicStates = dynamicStates
|
||||||
|
};
|
||||||
|
|
||||||
|
VkPipelineDepthStencilStateCreateInfo depthStencilState{
|
||||||
|
.sType = VK_STRUCTURE_TYPE_PIPELINE_DEPTH_STENCIL_STATE_CREATE_INFO,
|
||||||
|
.depthTestEnable = VK_FALSE,
|
||||||
|
.depthWriteEnable = VK_FALSE,
|
||||||
|
.depthCompareOp = VK_COMPARE_OP_ALWAYS,
|
||||||
|
.stencilTestEnable = VK_FALSE,
|
||||||
|
.front = {
|
||||||
|
.failOp = VK_STENCIL_OP_REPLACE,
|
||||||
|
.passOp = VK_STENCIL_OP_REPLACE,
|
||||||
|
.depthFailOp = VK_STENCIL_OP_REPLACE,
|
||||||
|
.compareOp = VK_COMPARE_OP_ALWAYS,
|
||||||
|
.compareMask = 0x01,
|
||||||
|
.writeMask = 0x01,
|
||||||
|
.reference = 1,
|
||||||
|
},
|
||||||
|
.back = {
|
||||||
|
.failOp = VK_STENCIL_OP_REPLACE,
|
||||||
|
.passOp = VK_STENCIL_OP_REPLACE,
|
||||||
|
.depthFailOp = VK_STENCIL_OP_REPLACE,
|
||||||
|
.compareOp = VK_COMPARE_OP_ALWAYS,
|
||||||
|
.compareMask = 0x01,
|
||||||
|
.writeMask = 0x01,
|
||||||
|
.reference = 1,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
VkPipelineRenderingCreateInfo renderingCreateInfo{
|
||||||
|
.sType = VK_STRUCTURE_TYPE_PIPELINE_RENDERING_CREATE_INFO,
|
||||||
|
.colorAttachmentCount = 1,
|
||||||
|
.pColorAttachmentFormats = &colorFormat,
|
||||||
|
.depthAttachmentFormat = depthFormat,
|
||||||
|
.stencilAttachmentFormat = depthFormat
|
||||||
|
};
|
||||||
|
|
||||||
|
VkPipelineColorBlendAttachmentState blendAttachment{
|
||||||
|
.blendEnable = VK_FALSE,
|
||||||
|
.srcColorBlendFactor = VK_BLEND_FACTOR_ONE,
|
||||||
|
.dstColorBlendFactor = VK_BLEND_FACTOR_ZERO,
|
||||||
|
.colorBlendOp = VK_BLEND_OP_ADD,
|
||||||
|
.srcAlphaBlendFactor = VK_BLEND_FACTOR_ONE,
|
||||||
|
.dstAlphaBlendFactor = VK_BLEND_FACTOR_ZERO,
|
||||||
|
.alphaBlendOp = VK_BLEND_OP_ADD,
|
||||||
|
.colorWriteMask = 0xF,
|
||||||
|
};
|
||||||
|
VkPipelineColorBlendStateCreateInfo colorBlendState{
|
||||||
|
.sType = VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO,
|
||||||
|
.attachmentCount = 1,
|
||||||
|
.pAttachments = &blendAttachment
|
||||||
|
};
|
||||||
|
VkPipelineRasterizationStateCreateInfo rasterizationState{
|
||||||
|
.sType = VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO,
|
||||||
|
//.cullMode = VK_CULL_MODE_BACK_BIT,
|
||||||
|
.cullMode = VK_CULL_MODE_NONE,
|
||||||
|
.frontFace = VK_FRONT_FACE_COUNTER_CLOCKWISE,
|
||||||
|
.lineWidth = 1.0f
|
||||||
|
};
|
||||||
|
VkPipelineMultisampleStateCreateInfo multisampleState{
|
||||||
|
.sType = VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO,
|
||||||
|
.rasterizationSamples = VK_SAMPLE_COUNT_1_BIT
|
||||||
|
};
|
||||||
|
|
||||||
|
constexpr int vertexBindingDescriptionsCount = 1;
|
||||||
|
VkVertexInputBindingDescription vertexBindingDescriptions[vertexBindingDescriptionsCount]{
|
||||||
|
{
|
||||||
|
.binding = 0,
|
||||||
|
.stride = perVertexSize,
|
||||||
|
.inputRate = VK_VERTEX_INPUT_RATE_VERTEX
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
constexpr int vertexAttributeDescriptionsCount = 2;
|
||||||
|
VkVertexInputAttributeDescription vertexAttributeDescriptions[vertexAttributeDescriptionsCount]{
|
||||||
|
// per-vertex
|
||||||
|
{ // position
|
||||||
|
.location = 0,
|
||||||
|
.binding = 0,
|
||||||
|
.format = VK_FORMAT_R16G16_SFLOAT,
|
||||||
|
.offset = 0,
|
||||||
|
},
|
||||||
|
{ // texture
|
||||||
|
.location = 1,
|
||||||
|
.binding = 0,
|
||||||
|
.format = VK_FORMAT_R16G16_SFLOAT,
|
||||||
|
.offset = 4,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
VkPipelineVertexInputStateCreateInfo vertexInputState{
|
||||||
|
.sType = VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO,
|
||||||
|
.vertexBindingDescriptionCount = vertexBindingDescriptionsCount,
|
||||||
|
.pVertexBindingDescriptions = vertexBindingDescriptions,
|
||||||
|
.vertexAttributeDescriptionCount = vertexAttributeDescriptionsCount,
|
||||||
|
.pVertexAttributeDescriptions = vertexAttributeDescriptions,
|
||||||
|
};
|
||||||
|
|
||||||
|
VkGraphicsPipelineCreateInfo pipelineCreateInfos[1]{
|
||||||
|
{
|
||||||
|
.sType = VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO,
|
||||||
|
.pNext = &renderingCreateInfo,
|
||||||
|
.stageCount = 2,
|
||||||
|
.pStages = shaderStages,
|
||||||
|
.pVertexInputState = &vertexInputState,
|
||||||
|
.pInputAssemblyState = &inputAssemblyState,
|
||||||
|
.pViewportState = &viewportState,
|
||||||
|
.pRasterizationState = &rasterizationState,
|
||||||
|
.pMultisampleState = &multisampleState,
|
||||||
|
.pDepthStencilState = &depthStencilState,
|
||||||
|
.pColorBlendState = &colorBlendState,
|
||||||
|
.pDynamicState = &dynamicState,
|
||||||
|
.layout = pipelineLayout
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
VK_CHECK(vkCreateGraphicsPipelines(device, VK_NULL_HANDLE, 1, pipelineCreateInfos, nullptr, &pipeline));
|
||||||
|
}
|
||||||
|
|
||||||
|
//////////////////////////////////////////////////////////////////////
|
||||||
|
// draw
|
||||||
|
//////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
void vulkan::draw(VkCommandBuffer commandBuffer,
|
||||||
|
uint32_t frameIndex,
|
||||||
|
float dissolveLerp,
|
||||||
|
float textLerp)
|
||||||
|
{
|
||||||
|
vkCmdBindPipeline(commandBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, pipeline);
|
||||||
|
|
||||||
|
float lerp[2] = { dissolveLerp, textLerp };
|
||||||
|
vkCmdPushConstants(commandBuffer, pipelineLayout, VK_SHADER_STAGE_VERTEX_BIT, 0, (sizeof (float)) * 2, lerp);
|
||||||
|
|
||||||
|
VkDescriptorSet descriptorSets[1] = {
|
||||||
|
descriptorSet0,
|
||||||
|
};
|
||||||
|
vkCmdBindDescriptorSets(commandBuffer,
|
||||||
|
VK_PIPELINE_BIND_POINT_GRAPHICS,
|
||||||
|
pipelineLayout,
|
||||||
|
0, 1, descriptorSets,
|
||||||
|
0, nullptr);
|
||||||
|
|
||||||
|
vkCmdBindIndexBuffer(commandBuffer, vertexIndex.buffer, vertexIndex.indexOffset, VK_INDEX_TYPE_UINT16);
|
||||||
|
|
||||||
|
VkDeviceSize vertexOffsets[1]{ 0 };
|
||||||
|
VkBuffer vertexBuffers[1]{ vertexIndex.buffer };
|
||||||
|
vkCmdBindVertexBuffers(commandBuffer, 0, 1, vertexBuffers, vertexOffsets);
|
||||||
|
|
||||||
|
vkCmdDrawIndexed(commandBuffer, 4, 1, 0, 0, 0);
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -22,7 +22,7 @@ namespace renpy {
|
|||||||
bool mDown = mLeft && (!lastmLeft);
|
bool mDown = mLeft && (!lastmLeft);
|
||||||
lastmLeft = mLeft;
|
lastmLeft = mLeft;
|
||||||
if (mDown) {
|
if (mDown) {
|
||||||
state.interactionWait = false;
|
state.pause.voice = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (state.menu.count == 0 || !mDown)
|
if (state.menu.count == 0 || !mDown)
|
||||||
|
|||||||
@ -10,13 +10,17 @@ namespace renpy {
|
|||||||
void interpreter::reset()
|
void interpreter::reset()
|
||||||
{
|
{
|
||||||
pc = 0;
|
pc = 0;
|
||||||
backgroundIndex = -1;
|
backgroundIndex = ~0u;
|
||||||
backgroundColor = 0;
|
backgroundColor = 0;
|
||||||
shownImagesCount = 0;
|
shownImagesCount = 0;
|
||||||
say.stringIndex = -1;
|
say.stringIndex = ~0u;
|
||||||
say.characterIndex = -1;
|
say.characterIndex = ~0u;
|
||||||
menu.count = 0;
|
menu.count = 0;
|
||||||
interactionWait = false;
|
dissolveIndex = 0;
|
||||||
|
pause.voice = false;
|
||||||
|
pause.menu = false;
|
||||||
|
pause.dissolve = false;
|
||||||
|
pause.pause = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
uint32_t interpreter::findImage(uint32_t imageIndex)
|
uint32_t interpreter::findImage(uint32_t imageIndex)
|
||||||
@ -60,6 +64,8 @@ namespace renpy {
|
|||||||
|
|
||||||
void interpreter::interpret_one()
|
void interpreter::interpret_one()
|
||||||
{
|
{
|
||||||
|
uint32_t last_pc = pc;
|
||||||
|
|
||||||
assert(pc < (uint32_t)script::statements_length);
|
assert(pc < (uint32_t)script::statements_length);
|
||||||
|
|
||||||
language::statement const& statement = script::statements[pc];
|
language::statement const& statement = script::statements[pc];
|
||||||
@ -90,8 +96,8 @@ namespace renpy {
|
|||||||
backgroundIndex = statement.scene.imageIndex;
|
backgroundIndex = statement.scene.imageIndex;
|
||||||
|
|
||||||
shownImagesCount = 0;
|
shownImagesCount = 0;
|
||||||
say.stringIndex = -1;
|
say.stringIndex = ~0u;
|
||||||
say.characterIndex = -1;
|
say.characterIndex = ~0u;
|
||||||
pc += 1;
|
pc += 1;
|
||||||
break;
|
break;
|
||||||
case language::type::say:
|
case language::type::say:
|
||||||
@ -99,7 +105,7 @@ namespace renpy {
|
|||||||
assert(statement.say.stringIndex < (uint32_t)script::strings_length);
|
assert(statement.say.stringIndex < (uint32_t)script::strings_length);
|
||||||
say.stringIndex = statement.say.stringIndex;
|
say.stringIndex = statement.say.stringIndex;
|
||||||
say.characterIndex = statement.say.characterIndex;
|
say.characterIndex = statement.say.characterIndex;
|
||||||
interactionWait = true;
|
pause.voice = true;
|
||||||
pc += 1;
|
pc += 1;
|
||||||
break;
|
break;
|
||||||
case language::type::hide:
|
case language::type::hide:
|
||||||
@ -129,22 +135,37 @@ namespace renpy {
|
|||||||
assert(statement.jump.statementIndex < (uint32_t)script::statements_length);
|
assert(statement.jump.statementIndex < (uint32_t)script::statements_length);
|
||||||
pc = statement.jump.statementIndex;
|
pc = statement.jump.statementIndex;
|
||||||
break;
|
break;
|
||||||
|
case language::type::pause:
|
||||||
|
fprintf(stderr, "interpret_one[%d]: pause %f\n", pc, statement.pause.duration);
|
||||||
|
pauseDuration = statement.pause.duration;
|
||||||
|
pause.pause = true;
|
||||||
|
pc += 1;
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
fprintf(stderr, "unknown statement type at pc %d\n", pc);
|
fprintf(stderr, "unknown statement type at pc %d\n", pc);
|
||||||
|
assert(false);
|
||||||
pc += 1;
|
pc += 1;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
assert(pc != last_pc);
|
||||||
}
|
}
|
||||||
|
|
||||||
void interpreter::interpret()
|
void interpreter::interpret()
|
||||||
{
|
{
|
||||||
while (!interactionWait) {
|
while (!interactionWait()) {
|
||||||
//while (true) {
|
if (dissolvePC()) {
|
||||||
uint32_t last_pc = pc;
|
fprintf(stderr, "dissolve pc %d\n", pc);
|
||||||
interpret_one();
|
language::dissolve const & dissolve = script::dissolves[dissolveIndex];
|
||||||
assert(pc != last_pc);
|
for (uint32_t i = 0; i < dissolve.count; i++) {
|
||||||
|
interpret_one();
|
||||||
//if (pc == 18) break;
|
}
|
||||||
|
pause.dissolve = true;
|
||||||
|
dissolveDuration = dissolve.duration;
|
||||||
|
dissolveIndex += 1;
|
||||||
|
} else {
|
||||||
|
interpret_one();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|||||||
@ -223,27 +223,41 @@ const int images_length = (sizeof (images)) / (sizeof (images[0]));
|
|||||||
const language::option options[] = {
|
const language::option options[] = {
|
||||||
{ .string = "Complain", .statementIndex = 19 }, // 0
|
{ .string = "Complain", .statementIndex = 19 }, // 0
|
||||||
{ .string = "Rationalize", .statementIndex = 27 }, // 1
|
{ .string = "Rationalize", .statementIndex = 27 }, // 1
|
||||||
{ .string = "Good idea", .statementIndex = 54 }, // 2
|
{ .string = "Good idea", .statementIndex = 53 }, // 2
|
||||||
{ .string = "I am too tired", .statementIndex = 61 }, // 3
|
{ .string = "I am too tired", .statementIndex = 60 }, // 3
|
||||||
{ .string = "Beg for mercy", .statementIndex = 78 }, // 4
|
{ .string = "Beg for mercy", .statementIndex = 77 }, // 4
|
||||||
{ .string = "Run", .statementIndex = 80 }, // 5
|
{ .string = "Run", .statementIndex = 79 }, // 5
|
||||||
};
|
};
|
||||||
|
|
||||||
const int options_length = (sizeof (options)) / (sizeof (options[0]));
|
const int options_length = (sizeof (options)) / (sizeof (options[0]));
|
||||||
|
|
||||||
|
const language::dissolve dissolves[] = {
|
||||||
|
{ .duration = 3.0, .first_statement = 4, .count = 1 },
|
||||||
|
{ .duration = 3.0, .first_statement = 11, .count = 1 },
|
||||||
|
{ .duration = 1.0, .first_statement = 34, .count = 2 },
|
||||||
|
{ .duration = 1.0, .first_statement = 39, .count = 1 },
|
||||||
|
{ .duration = 3.0, .first_statement = 116, .count = 2 },
|
||||||
|
{ .duration = 3.0, .first_statement = 120, .count = 1 },
|
||||||
|
{ .duration = 2.0, .first_statement = 195, .count = 2 },
|
||||||
|
{ .duration = 1.3, .first_statement = 199, .count = 3 },
|
||||||
|
{ .duration = 3.0, .first_statement = 241, .count = 1 },
|
||||||
|
};
|
||||||
|
|
||||||
|
const int dissolves_length = (sizeof (dissolves)) / (sizeof (dissolves[0]));
|
||||||
|
|
||||||
const language::statement statements[] = {
|
const language::statement statements[] = {
|
||||||
{ .type = type::play, .play = { .audioIndex = 0 } }, // 0 sfx/Chime.ogg
|
{ .type = type::play, .play = { .audioIndex = 0 } }, // 0 sfx/Chime.ogg
|
||||||
{ .type = type::play, .play = { .audioIndex = 1 } }, // 1 sfx/MistAmbience.ogg
|
{ .type = type::play, .play = { .audioIndex = 1 } }, // 1 sfx/MistAmbience.ogg
|
||||||
{ .type = type::scene_color, .scene_color = { .color = 0xffffff } }, // 2 bgwhite
|
{ .type = type::scene_color, .scene_color = { .color = 0x000000 } }, // 2 bgblack
|
||||||
{ .type = type::dissolve, .dissolve = { .duration = 3.0 } }, // 3
|
{ .type = type::pause, .pause = { .duration = 0.0 } }, // 3
|
||||||
{ .type = type::say, .say = { .characterIndex = 4, .stringIndex = 0 } }, // 4 n "Far over the mountains of Almystice"
|
{ .type = type::scene_color, .scene_color = { .color = 0xffffff } }, // 4 bgwhite
|
||||||
{ .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 = 0 } }, // 5 n "Far over the mountains of Almystice"
|
||||||
{ .type = type::say, .say = { .characterIndex = 4, .stringIndex = 2 } }, // 6 n "And across the vast fields of Alysen"
|
{ .type = type::say, .say = { .characterIndex = 4, .stringIndex = 1 } }, // 6 n "Beyond the tumultuous waters of the Lilac Bay"
|
||||||
{ .type = type::play, .play = { .audioIndex = 2 } }, // 7 music/TinyForestMinstrels.ogg
|
{ .type = type::say, .say = { .characterIndex = 4, .stringIndex = 2 } }, // 7 n "And across the vast fields of Alysen"
|
||||||
{ .type = type::say, .say = { .characterIndex = 4, .stringIndex = 3 } }, // 8 n "Tiny minstrels can be heard amongst the trees"
|
{ .type = type::play, .play = { .audioIndex = 2 } }, // 8 music/TinyForestMinstrels.ogg
|
||||||
{ .type = type::stop, .stop = { .audioIndex = 2, .fadeout = 5.5 } }, // 9 TinyForestMinstrels
|
{ .type = type::say, .say = { .characterIndex = 4, .stringIndex = 3 } }, // 9 n "Tiny minstrels can be heard amongst the trees"
|
||||||
{ .type = type::scene, .scene = { .imageIndex = 1 } }, // 10 bgforest1
|
{ .type = type::stop, .stop = { .audioIndex = 2, .fadeout = 5.5 } }, // 10 TinyForestMinstrels
|
||||||
{ .type = type::dissolve, .dissolve = { .duration = 3.0 } }, // 11
|
{ .type = type::scene, .scene = { .imageIndex = 1 } }, // 11 bgforest1
|
||||||
{ .type = type::show, .show = { .imageIndex = 8, .transformIndex = transform::left } }, // 12 al
|
{ .type = type::show, .show = { .imageIndex = 8, .transformIndex = transform::left } }, // 12 al
|
||||||
{ .type = type::say, .say = { .characterIndex = 0, .stringIndex = 4 } }, // 13 a "Are we almost there?"
|
{ .type = type::say, .say = { .characterIndex = 0, .stringIndex = 4 } }, // 13 a "Are we almost there?"
|
||||||
{ .type = type::show, .show = { .imageIndex = 7, .transformIndex = transform::right } }, // 14 ei
|
{ .type = type::show, .show = { .imageIndex = 7, .transformIndex = transform::right } }, // 14 ei
|
||||||
@ -268,218 +282,215 @@ const language::statement statements[] = {
|
|||||||
{ .type = type::stop, .stop = { .audioIndex = 2, .fadeout = 5.5 } }, // 33 TinyForestMinstrels
|
{ .type = type::stop, .stop = { .audioIndex = 2, .fadeout = 5.5 } }, // 33 TinyForestMinstrels
|
||||||
{ .type = type::scene_color, .scene_color = { .color = 0xffffff } }, // 34 bgwhite
|
{ .type = type::scene_color, .scene_color = { .color = 0xffffff } }, // 34 bgwhite
|
||||||
{ .type = type::play, .play = { .audioIndex = 0 } }, // 35 sfx/Chime.ogg
|
{ .type = type::play, .play = { .audioIndex = 0 } }, // 35 sfx/Chime.ogg
|
||||||
{ .type = type::dissolve, .dissolve = { .duration = 1.0 } }, // 36
|
{ .type = type::play, .play = { .audioIndex = 0 } }, // 36 sfx/Chime.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::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 = 3 } }, // 38 music/PhrygianButterflies.ogg
|
{ .type = type::play, .play = { .audioIndex = 3 } }, // 38 music/PhrygianButterflies.ogg
|
||||||
{ .type = type::scene, .scene = { .imageIndex = 3 } }, // 39 bgflower1
|
{ .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 } }, // 40 ei
|
||||||
{ .type = type::show, .show = { .imageIndex = 7, .transformIndex = transform::right } }, // 41 ei
|
{ .type = type::say, .say = { .characterIndex = 2, .stringIndex = 19 } }, // 41 e "Look at all the butterflies! They are all so pretty!"
|
||||||
{ .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 } }, // 42 al
|
||||||
{ .type = type::show, .show = { .imageIndex = 8, .transformIndex = transform::left } }, // 43 al
|
{ .type = type::say, .say = { .characterIndex = 0, .stringIndex = 20 } }, // 43 a "This place is like a dream..."
|
||||||
{ .type = type::say, .say = { .characterIndex = 0, .stringIndex = 20 } }, // 44 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 = 21 } }, // 45 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 = 2, .stringIndex = 22 } }, // 46 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 = 0, .stringIndex = 23 } }, // 47 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 = 24 } }, // 48 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 = 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 } }, // 49 a "I told you not to eat them all!"
|
||||||
{ .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 } }, // 50 e "Yah yah"
|
||||||
{ .type = type::say, .say = { .characterIndex = 2, .stringIndex = 27 } }, // 51 e "Yah yah"
|
{ .type = type::say, .say = { .characterIndex = 2, .stringIndex = 28 } }, // 51 e "Anyways, shall I recite a tale?"
|
||||||
{ .type = type::say, .say = { .characterIndex = 2, .stringIndex = 28 } }, // 52 e "Anyways, shall I recite a tale?"
|
{ .type = type::menu, .menu = { .count = 2, .optionIndex = 2 } }, // 52 "Good idea", "I am too tired"
|
||||||
{ .type = type::menu, .menu = { .count = 2, .optionIndex = 2 } }, // 53 "Good idea", "I am too tired"
|
{ .type = type::stop, .stop = { .audioIndex = 3, .fadeout = 4.2 } }, // 53 PhrygianButterflies
|
||||||
{ .type = type::stop, .stop = { .audioIndex = 3, .fadeout = 4.2 } }, // 54 PhrygianButterflies
|
{ .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 = 0, .stringIndex = 29 } }, // 55 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 = 2, .stringIndex = 30 } }, // 56 e "Sure"
|
{ .type = type::say, .say = { .characterIndex = 0, .stringIndex = 31 } }, // 56 a "..."
|
||||||
{ .type = type::say, .say = { .characterIndex = 0, .stringIndex = 31 } }, // 57 a "..."
|
{ .type = type::play, .play = { .audioIndex = 4 } }, // 57 music/Poem1.ogg
|
||||||
{ .type = type::play, .play = { .audioIndex = 4 } }, // 58 music/Poem1.ogg
|
{ .type = type::pause, .pause = { .duration = 40 } }, // 58
|
||||||
{ .type = type::pause, .pause = { .duration = 40 } }, // 59
|
{ .type = type::jump, .jump = { .statementIndex = 64 } }, // 59 internal jump (b'__menu_end', 1)
|
||||||
{ .type = type::jump, .jump = { .statementIndex = 65 } }, // 60 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::say, .say = { .characterIndex = 2, .stringIndex = 32 } }, // 61 e "Serves you right for scaring those elephant-dogs"
|
{ .type = type::stop, .stop = { .audioIndex = 3, .fadeout = 4.2 } }, // 61 PhrygianButterflies
|
||||||
{ .type = type::stop, .stop = { .audioIndex = 3, .fadeout = 4.2 } }, // 62 PhrygianButterflies
|
{ .type = type::say, .say = { .characterIndex = 0, .stringIndex = 33 } }, // 62 a "They were asking for it, you know"
|
||||||
{ .type = type::say, .say = { .characterIndex = 0, .stringIndex = 33 } }, // 63 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 internal jump (b'__menu_end', 1)
|
{ .type = type::jump, .jump = { .statementIndex = 65 } }, // 64 mainbranch2
|
||||||
{ .type = type::jump, .jump = { .statementIndex = 66 } }, // 65 mainbranch2
|
{ .type = type::hide, .hide = { .imageIndex = 7 } }, // 65 ei
|
||||||
{ .type = type::hide, .hide = { .imageIndex = 7 } }, // 66 ei
|
{ .type = type::show, .show = { .imageIndex = 6, .transformIndex = transform::right } }, // 66 catw
|
||||||
{ .type = type::show, .show = { .imageIndex = 6, .transformIndex = transform::right } }, // 67 catw
|
{ .type = type::show, .show = { .imageIndex = 7, .transformIndex = transform::centerleft } }, // 67 ei
|
||||||
{ .type = type::show, .show = { .imageIndex = 7, .transformIndex = transform::centerleft } }, // 68 ei
|
{ .type = type::voice, .voice = { .audioIndex = 5 } }, // 68 placeholdermeow.mp3
|
||||||
{ .type = type::voice, .voice = { .audioIndex = 5 } }, // 69 placeholdermeow.mp3
|
{ .type = type::say, .say = { .characterIndex = 1, .stringIndex = 34 } }, // 69 c "Rawrrrr"
|
||||||
{ .type = type::say, .say = { .characterIndex = 1, .stringIndex = 34 } }, // 70 c "Rawrrrr"
|
{ .type = type::hide, .hide = { .imageIndex = 6 } }, // 70 catw
|
||||||
{ .type = type::hide, .hide = { .imageIndex = 6 } }, // 71 catw
|
{ .type = type::show, .show = { .imageIndex = 5, .transformIndex = transform::right } }, // 71 cat
|
||||||
{ .type = type::show, .show = { .imageIndex = 5, .transformIndex = transform::right } }, // 72 cat
|
{ .type = type::play, .play = { .audioIndex = 6 } }, // 72 music/ScaredMice.ogg
|
||||||
{ .type = type::play, .play = { .audioIndex = 6 } }, // 73 music/ScaredMice.ogg
|
{ .type = type::say, .say = { .characterIndex = 3, .stringIndex = 35 } }, // 73 mg "AHHHHHHHHHH!!!!!"
|
||||||
{ .type = type::say, .say = { .characterIndex = 3, .stringIndex = 35 } }, // 74 mg "AHHHHHHHHHH!!!!!"
|
{ .type = type::say, .say = { .characterIndex = 1, .stringIndex = 36 } }, // 74 c "Nyanyanyanya"
|
||||||
{ .type = type::say, .say = { .characterIndex = 1, .stringIndex = 36 } }, // 75 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::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 } }, // 76 "Beg for mercy", "Run"
|
||||||
{ .type = type::menu, .menu = { .count = 2, .optionIndex = 4 } }, // 77 "Beg for mercy", "Run"
|
{ .type = type::say, .say = { .characterIndex = 0, .stringIndex = 38 } }, // 77 a "Please don't eat us!!!"
|
||||||
{ .type = type::say, .say = { .characterIndex = 0, .stringIndex = 38 } }, // 78 a "Please don't eat us!!!"
|
{ .type = type::jump, .jump = { .statementIndex = 82 } }, // 78 internal jump (b'__menu_end', 2)
|
||||||
{ .type = type::jump, .jump = { .statementIndex = 83 } }, // 79 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 = 39 } }, // 80 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::say, .say = { .characterIndex = 2, .stringIndex = 40 } }, // 81 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 internal jump (b'__menu_end', 2)
|
{ .type = type::jump, .jump = { .statementIndex = 83 } }, // 82 mainbranch3
|
||||||
{ .type = type::jump, .jump = { .statementIndex = 84 } }, // 83 mainbranch3
|
{ .type = type::stop, .stop = { .audioIndex = 6, .fadeout = 2.0 } }, // 83 ScaredMice
|
||||||
{ .type = type::stop, .stop = { .audioIndex = 6, .fadeout = 2.0 } }, // 84 ScaredMice
|
{ .type = type::say, .say = { .characterIndex = 1, .stringIndex = 41 } }, // 84 c "I'm not gonna eat you nyanyanya"
|
||||||
{ .type = type::say, .say = { .characterIndex = 1, .stringIndex = 41 } }, // 85 c "I'm not gonna eat you nyanyanya"
|
{ .type = type::play, .play = { .audioIndex = 2 } }, // 85 music/TinyForestMinstrels.ogg
|
||||||
{ .type = type::play, .play = { .audioIndex = 2 } }, // 86 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 = 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 } }, // 87 c "Also, are you minstrels?"
|
||||||
{ .type = type::say, .say = { .characterIndex = 1, .stringIndex = 43 } }, // 88 c "Also, are you minstrels?"
|
{ .type = type::say, .say = { .characterIndex = 2, .stringIndex = 44 } }, // 88 e "Y-Yes"
|
||||||
{ .type = type::say, .say = { .characterIndex = 2, .stringIndex = 44 } }, // 89 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 = 0, .stringIndex = 45 } }, // 90 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 = 2, .stringIndex = 46 } }, // 91 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 = 47 } }, // 92 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 = 1, .stringIndex = 48 } }, // 93 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 = 2, .stringIndex = 49 } }, // 94 e "You don't say..."
|
{ .type = type::say, .say = { .characterIndex = 1, .stringIndex = 50 } }, // 94 c "Yah, I do actually"
|
||||||
{ .type = type::say, .say = { .characterIndex = 1, .stringIndex = 50 } }, // 95 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 = 2, .stringIndex = 51 } }, // 96 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 = 1, .stringIndex = 52 } }, // 97 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 = 2, .stringIndex = 53 } }, // 98 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 = 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 } }, // 99 e "Really? That must mean you are a noble?"
|
||||||
{ .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 } }, // 100 c "Well, not really..."
|
||||||
{ .type = type::say, .say = { .characterIndex = 1, .stringIndex = 56 } }, // 101 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 = 1, .stringIndex = 57 } }, // 102 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 = 58 } }, // 103 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 = 2, .stringIndex = 59 } }, // 104 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 = 1, .stringIndex = 60 } }, // 105 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 = 0, .stringIndex = 61 } }, // 106 a "Then why are you traveling to Castle Alysen?"
|
{ .type = type::say, .say = { .characterIndex = 1, .stringIndex = 62 } }, // 106 c "uhhh"
|
||||||
{ .type = type::say, .say = { .characterIndex = 1, .stringIndex = 62 } }, // 107 c "uhhh"
|
{ .type = type::play, .play = { .audioIndex = 1 } }, // 107 sfx/MistAmbience.ogg
|
||||||
{ .type = type::play, .play = { .audioIndex = 1 } }, // 108 sfx/MistAmbience.ogg
|
{ .type = type::stop, .stop = { .audioIndex = 2, .fadeout = 2.0 } }, // 108 TinyForestMinstrels
|
||||||
{ .type = type::stop, .stop = { .audioIndex = 2, .fadeout = 2.0 } }, // 109 TinyForestMinstrels
|
{ .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 = 63 } }, // 110 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::say, .say = { .characterIndex = 1, .stringIndex = 64 } }, // 111 c "GOOD DAY!"
|
{ .type = type::hide, .hide = { .imageIndex = 5 } }, // 111 cat
|
||||||
{ .type = type::hide, .hide = { .imageIndex = 5 } }, // 112 cat
|
{ .type = type::say, .say = { .characterIndex = 0, .stringIndex = 65 } }, // 112 a "Wha..."
|
||||||
{ .type = type::say, .say = { .characterIndex = 0, .stringIndex = 65 } }, // 113 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 = 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 } }, // 114 a "She didn't seem so bad"
|
||||||
{ .type = type::say, .say = { .characterIndex = 0, .stringIndex = 67 } }, // 115 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::say, .say = { .characterIndex = 2, .stringIndex = 68 } }, // 116 e "Are you kidding? She's a crazy kitty!"
|
{ .type = type::scene_color, .scene_color = { .color = 0xffffff } }, // 116 bgwhite
|
||||||
{ .type = type::scene_color, .scene_color = { .color = 0xffffff } }, // 117 bgwhite
|
{ .type = type::play, .play = { .audioIndex = 0 } }, // 117 sfx/Chime.ogg
|
||||||
{ .type = type::play, .play = { .audioIndex = 0 } }, // 118 sfx/Chime.ogg
|
{ .type = type::play, .play = { .audioIndex = 0 } }, // 118 sfx/Chime.ogg
|
||||||
{ .type = type::dissolve, .dissolve = { .duration = 3.0 } }, // 119
|
{ .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::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 } }, // 120 bgforest2
|
||||||
{ .type = type::scene, .scene = { .imageIndex = 2 } }, // 121 bgforest2
|
{ .type = type::show, .show = { .imageIndex = 7, .transformIndex = transform::right } }, // 121 ei
|
||||||
{ .type = type::dissolve, .dissolve = { .duration = 3.0 } }, // 122
|
{ .type = type::say, .say = { .characterIndex = 2, .stringIndex = 70 } }, // 122 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 } }, // 123 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 } }, // 124 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 } }, // 125 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 } }, // 126 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 } }, // 127 ei
|
||||||
{ .type = type::say, .say = { .characterIndex = 0, .stringIndex = 73 } }, // 128 a "Did you hear that?!?!"
|
{ .type = type::show, .show = { .imageIndex = 5, .transformIndex = transform::right } }, // 128 cat
|
||||||
{ .type = type::show, .show = { .imageIndex = 7, .transformIndex = transform::centerleft } }, // 129 ei
|
{ .type = type::play, .play = { .audioIndex = 3 } }, // 129 music/PhrygianButterflies.ogg
|
||||||
{ .type = type::show, .show = { .imageIndex = 5, .transformIndex = transform::right } }, // 130 cat
|
{ .type = type::say, .say = { .characterIndex = 1, .stringIndex = 74 } }, // 130 c "Hey there..."
|
||||||
{ .type = type::play, .play = { .audioIndex = 3 } }, // 131 music/PhrygianButterflies.ogg
|
{ .type = type::say, .say = { .characterIndex = 1, .stringIndex = 75 } }, // 131 c "I apologize"
|
||||||
{ .type = type::say, .say = { .characterIndex = 1, .stringIndex = 74 } }, // 132 c "Hey there..."
|
{ .type = type::say, .say = { .characterIndex = 1, .stringIndex = 76 } }, // 132 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 } }, // 133 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 } }, // 134 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 } }, // 135 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 } }, // 136 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 } }, // 137 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 } }, // 138 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 } }, // 139 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 } }, // 140 c "So then..."
|
||||||
{ .type = type::say, .say = { .characterIndex = 0, .stringIndex = 83 } }, // 141 a "Ahhhhhh"
|
{ .type = type::say, .say = { .characterIndex = 1, .stringIndex = 85 } }, // 141 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 } }, // 142 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 } }, // 143 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 } }, // 144 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 } }, // 145 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 } }, // 146 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 } }, // 147 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 } }, // 148 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 } }, // 149 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 } }, // 150 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 } }, // 151 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 } }, // 152 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 } }, // 153 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 } }, // 154 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 } }, // 155 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 } }, // 156 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 } }, // 157 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 } }, // 158 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 } }, // 159 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 } }, // 160 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 } }, // 161 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 } }, // 162 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 } }, // 163 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 } }, // 164 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 } }, // 165 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 } }, // 166 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 } }, // 167 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 } }, // 168 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 } }, // 169 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 } }, // 170 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 } }, // 171 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 } }, // 172 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 } }, // 173 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 } }, // 174 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 } }, // 175 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 } }, // 176 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 } }, // 177 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 } }, // 178 a "Hahahaha"
|
||||||
{ .type = type::say, .say = { .characterIndex = 2, .stringIndex = 121 } }, // 179 e "But so are we!"
|
{ .type = type::say, .say = { .characterIndex = 1, .stringIndex = 123 } }, // 179 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 } }, // 180 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 } }, // 181 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 } }, // 182 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 } }, // 183 mg "..."
|
||||||
{ .type = type::say, .say = { .characterIndex = 1, .stringIndex = 126 } }, // 184 c "Absolute madness!"
|
{ .type = type::say, .say = { .characterIndex = 1, .stringIndex = 127 } }, // 184 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 } }, // 185 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 } }, // 186 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 } }, // 187 e "Ha ha... Okay..."
|
||||||
{ .type = type::say, .say = { .characterIndex = 0, .stringIndex = 129 } }, // 188 a "Alright!"
|
{ .type = type::say, .say = { .characterIndex = 1, .stringIndex = 131 } }, // 188 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 } }, // 189 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 } }, // 190 a "Sounds good!"
|
||||||
{ .type = type::hide, .hide = { .imageIndex = 5 } }, // 191 cat
|
{ .type = type::hide, .hide = { .imageIndex = 8 } }, // 191 al
|
||||||
{ .type = type::say, .say = { .characterIndex = 0, .stringIndex = 132 } }, // 192 a "Sounds good!"
|
{ .type = type::stop, .stop = { .audioIndex = 3, .fadeout = 2.0 } }, // 192 PhrygianButterflies
|
||||||
{ .type = type::hide, .hide = { .imageIndex = 8 } }, // 193 al
|
{ .type = type::say, .say = { .characterIndex = 2, .stringIndex = 133 } }, // 193 e "Oh dear!"
|
||||||
{ .type = type::stop, .stop = { .audioIndex = 3, .fadeout = 2.0 } }, // 194 PhrygianButterflies
|
{ .type = type::hide, .hide = { .imageIndex = 7 } }, // 194 ei
|
||||||
{ .type = type::say, .say = { .characterIndex = 2, .stringIndex = 133 } }, // 195 e "Oh dear!"
|
{ .type = type::scene_color, .scene_color = { .color = 0xffffff } }, // 195 bgwhite
|
||||||
{ .type = type::hide, .hide = { .imageIndex = 7 } }, // 196 ei
|
{ .type = type::play, .play = { .audioIndex = 0 } }, // 196 sfx/Chime.ogg
|
||||||
{ .type = type::scene_color, .scene_color = { .color = 0xffffff } }, // 197 bgwhite
|
{ .type = type::play, .play = { .audioIndex = 0 } }, // 197 sfx/Chime.ogg
|
||||||
{ .type = type::play, .play = { .audioIndex = 0 } }, // 198 sfx/Chime.ogg
|
{ .type = type::say, .say = { .characterIndex = 4, .stringIndex = 134 } }, // 198 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 } }, // 199 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 } }, // 200 music/WheatFields.ogg
|
||||||
{ .type = type::scene, .scene = { .imageIndex = 4 } }, // 201 bgwheatfield1
|
{ .type = type::show, .show = { .imageIndex = 5, .transformIndex = transform::right } }, // 201 cat
|
||||||
{ .type = type::play, .play = { .audioIndex = 7 } }, // 202 music/WheatFields.ogg
|
{ .type = type::show, .show = { .imageIndex = 5, .transformIndex = transform::right } }, // 202 cat
|
||||||
{ .type = type::show, .show = { .imageIndex = 5, .transformIndex = transform::right } }, // 203 cat
|
{ .type = type::say, .say = { .characterIndex = 1, .stringIndex = 135 } }, // 203 c "Nya"
|
||||||
{ .type = type::dissolve, .dissolve = { .duration = 1.3 } }, // 204
|
{ .type = type::show, .show = { .imageIndex = 8, .transformIndex = transform::left } }, // 204 al
|
||||||
{ .type = type::say, .say = { .characterIndex = 1, .stringIndex = 135 } }, // 205 c "Nya"
|
{ .type = type::say, .say = { .characterIndex = 0, .stringIndex = 136 } }, // 205 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 } }, // 206 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 } }, // 207 e "Wait up"
|
||||||
{ .type = type::show, .show = { .imageIndex = 7, .transformIndex = transform::centerleft } }, // 208 ei
|
{ .type = type::say, .say = { .characterIndex = 1, .stringIndex = 138 } }, // 208 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 } }, // 209 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 } }, // 210 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 } }, // 211 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 } }, // 212 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 } }, // 213 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 } }, // 214 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 } }, // 215 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 } }, // 216 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 } }, // 217 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 } }, // 218 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 } }, // 219 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 } }, // 220 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 } }, // 221 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 } }, // 222 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 } }, // 223 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 } }, // 224 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 } }, // 225 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 } }, // 226 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 } }, // 227 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 } }, // 228 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 } }, // 229 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 } }, // 230 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 } }, // 231 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 } }, // 232 c "Nyanyanya"
|
||||||
{ .type = type::say, .say = { .characterIndex = 3, .stringIndex = 161 } }, // 233 mg "What?"
|
{ .type = type::say, .say = { .characterIndex = 1, .stringIndex = 163 } }, // 233 c "Nyevermind"
|
||||||
{ .type = type::say, .say = { .characterIndex = 1, .stringIndex = 162 } }, // 234 c "Nyanyanya"
|
{ .type = type::say, .say = { .characterIndex = 1, .stringIndex = 164 } }, // 234 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 } }, // 235 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 } }, // 236 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 } }, // 237 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 } }, // 238 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 } }, // 239 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 } }, // 240 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 } }, // 241 bgwhite
|
||||||
{ .type = type::say, .say = { .characterIndex = 5, .stringIndex = 170 } }, // 242 l "My name is Leona!"
|
{ .type = type::say, .say = { .characterIndex = 4, .stringIndex = 171 } }, // 242 n "And so, the odd trio walked through the wheatfields and towards the castle walls"
|
||||||
{ .type = type::scene_color, .scene_color = { .color = 0xffffff } }, // 243 bgwhite
|
{ .type = type::say, .say = { .characterIndex = 4, .stringIndex = 172 } }, // 243 n "Upon approaching the castle walls"
|
||||||
{ .type = type::dissolve, .dissolve = { .duration = 3.0 } }, // 244
|
{ .type = type::_return }, // 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
|
|
||||||
};
|
};
|
||||||
|
|
||||||
const int statements_length = (sizeof (statements)) / (sizeof (statements[0]));
|
const int statements_length = (sizeof (statements)) / (sizeof (statements[0]));
|
||||||
|
|||||||
@ -514,11 +514,62 @@ namespace renpy {
|
|||||||
// draw
|
// draw
|
||||||
//////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
void vulkan::draw_menu_frame(VkCommandBuffer commandBuffer,
|
||||||
|
uint32_t frameIndex,
|
||||||
|
renpy::interpreter const& state,
|
||||||
|
int & outputIndex,
|
||||||
|
int mx, int my) const
|
||||||
|
{
|
||||||
|
for (uint32_t i = 0; i < state.menu.count; i++) {
|
||||||
|
int y = menu::yStride * i + menu::y;
|
||||||
|
|
||||||
|
bool overlap = renpy::overlap(menu::width, menu::height, menu::x, y, mx, my);
|
||||||
|
instanceMappedData[maximumImageCount * frameIndex + outputIndex++] = {
|
||||||
|
.size = {menu::width, menu::height},
|
||||||
|
.topLeft = {menu::x, (int16_t)(y)},
|
||||||
|
.color = overlap ? 0xf0494493u : 0xa0ffffffu,
|
||||||
|
.imageIndex = -3, // white gradient 2
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void vulkan::draw_say_frame(VkCommandBuffer commandBuffer,
|
||||||
|
uint32_t frameIndex,
|
||||||
|
renpy::interpreter const& state,
|
||||||
|
int & outputIndex) const
|
||||||
|
{
|
||||||
|
instanceMappedData[maximumImageCount * frameIndex + outputIndex++] = {
|
||||||
|
.size = {708, 200},
|
||||||
|
.topLeft = {286, 720 - 200},
|
||||||
|
.color = 0x80ffffffu,
|
||||||
|
.imageIndex = -2, // white gradient 1
|
||||||
|
};
|
||||||
|
instanceMappedData[maximumImageCount * frameIndex + outputIndex++] = {
|
||||||
|
.size = {244, 200},
|
||||||
|
.topLeft = {336, 720 - 200},
|
||||||
|
.imageIndex = 0, // flower
|
||||||
|
};
|
||||||
|
instanceMappedData[maximumImageCount * frameIndex + outputIndex++] = {
|
||||||
|
.size = {-244, 200},
|
||||||
|
.topLeft = {1280 - (336 + 244), 720 - 200},
|
||||||
|
.imageIndex = 0, // flower
|
||||||
|
};
|
||||||
|
|
||||||
|
if (state.say.characterIndex != -1u) {
|
||||||
|
instanceMappedData[maximumImageCount * frameIndex + outputIndex++] = {
|
||||||
|
.size = {148, 30},
|
||||||
|
.topLeft = {560, 528},
|
||||||
|
.color = 0x80ffffffu,
|
||||||
|
.imageIndex = -4, // white gradient 2
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void vulkan::draw(VkCommandBuffer commandBuffer,
|
void vulkan::draw(VkCommandBuffer commandBuffer,
|
||||||
uint32_t frameIndex,
|
uint32_t frameIndex,
|
||||||
renpy::interpreter const& state,
|
renpy::interpreter const& state,
|
||||||
int mx,
|
int mx, int my,
|
||||||
int my)
|
bool drawText) const
|
||||||
{
|
{
|
||||||
int outputIndex = 0;
|
int outputIndex = 0;
|
||||||
// update
|
// update
|
||||||
@ -538,43 +589,11 @@ namespace renpy {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
if (state.menu.count == 0) {
|
if (drawText) {
|
||||||
instanceMappedData[maximumImageCount * frameIndex + outputIndex++] = {
|
if (state.menu.count != 0) {
|
||||||
.size = {708, 200},
|
draw_menu_frame(commandBuffer, frameIndex, state, outputIndex, mx, my);
|
||||||
.topLeft = {286, 720 - 200},
|
} else if (state.say.stringIndex != ~0u) {
|
||||||
.color = 0x80ffffffu,
|
draw_say_frame(commandBuffer, frameIndex, state, outputIndex);
|
||||||
.imageIndex = -2, // white gradient 1
|
|
||||||
};
|
|
||||||
instanceMappedData[maximumImageCount * frameIndex + outputIndex++] = {
|
|
||||||
.size = {244, 200},
|
|
||||||
.topLeft = {336, 720 - 200},
|
|
||||||
.imageIndex = 0, // flower
|
|
||||||
};
|
|
||||||
instanceMappedData[maximumImageCount * frameIndex + outputIndex++] = {
|
|
||||||
.size = {-244, 200},
|
|
||||||
.topLeft = {1280 - (336 + 244), 720 - 200},
|
|
||||||
.imageIndex = 0, // flower
|
|
||||||
};
|
|
||||||
|
|
||||||
if (state.say.characterIndex != -1u) {
|
|
||||||
instanceMappedData[maximumImageCount * frameIndex + outputIndex++] = {
|
|
||||||
.size = {148, 30},
|
|
||||||
.topLeft = {560, 528},
|
|
||||||
.color = 0x80ffffffu,
|
|
||||||
.imageIndex = -4, // white gradient 2
|
|
||||||
};
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
for (uint32_t i = 0; i < state.menu.count; i++) {
|
|
||||||
int y = menu::yStride * i + menu::y;
|
|
||||||
|
|
||||||
bool overlap = renpy::overlap(menu::width, menu::height, menu::x, y, mx, my);
|
|
||||||
instanceMappedData[maximumImageCount * frameIndex + outputIndex++] = {
|
|
||||||
.size = {menu::width, menu::height},
|
|
||||||
.topLeft = {menu::x, (int16_t)(y)},
|
|
||||||
.color = overlap ? 0xf0494493u : 0xa0ffffffu,
|
|
||||||
.imageIndex = -3, // white gradient 2
|
|
||||||
};
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -1,2 +1 @@
|
|||||||
export VK_INSTANCE_LAYERS=VK_LAYER_KHRONOS_validation
|
export VK_INSTANCE_LAYERS=VK_LAYER_KHRONOS_validation
|
||||||
export VK_VALIDATION_VALIDATE_SYNC=1
|
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user