Compare commits
No commits in common. "5a0299d9dd498b3829102a4e97d8bbf736970dd2" and "e3ffcce26f2700e0cb070500cad127e6b3bfb1a2" have entirely different histories.
5a0299d9dd
...
e3ffcce26f
3
.gitignore
vendored
@ -6,5 +6,4 @@ main
|
||||
tool/pack_file
|
||||
*.zip
|
||||
*.tar
|
||||
*.pyc
|
||||
*.dds
|
||||
*.pyc
|
||||
36
Makefile
@ -7,7 +7,7 @@ OBJARCH = elf64-x86-64
|
||||
|
||||
UNAME := $(shell uname -s)
|
||||
|
||||
OPT += -O3 -march=x86-64-v3
|
||||
OPT += -O0 -march=x86-64-v3
|
||||
|
||||
DEBUG = -g
|
||||
|
||||
@ -24,14 +24,10 @@ CFLAGS += -I./include
|
||||
CFLAGS += -I./data
|
||||
CFLAGS += -I../SDL3-dist/include
|
||||
CFLAGS += -fpic
|
||||
CFLAGS += -ffunction-sections
|
||||
CFLAGS += -fdata-sections
|
||||
|
||||
#FLAGS += -fstack-protector -fstack-protector-all -fno-omit-frame-pointer -fsanitize=address
|
||||
|
||||
LDFLAGS += -lm
|
||||
LDFLAGS += -Wl,--gc-sections
|
||||
#-Wl,--print-gc-sections
|
||||
ifeq ($(UNAME),Linux)
|
||||
LDFLAGS += -Wl,-z noexecstack
|
||||
endif
|
||||
@ -40,16 +36,6 @@ LDFLAGS += -framework Foundation -framework Cocoa -framework IOKit -framework AV
|
||||
LDFLAGS += -lstdc++
|
||||
endif
|
||||
|
||||
# src/collada/scene/vulkan.o \
|
||||
# src/collada/scene/reload.o \
|
||||
# src/collada/scene.o \
|
||||
# src/collada/node_state.o \
|
||||
# src/collada/animate.o \
|
||||
# src/minecraft/world.o \
|
||||
# src/minecraft/entry_table.o \
|
||||
# src/minecraft/vulkan.o \
|
||||
# src/minecraft/vulkan/per_world.o \
|
||||
|
||||
OBJS = \
|
||||
src/main.o \
|
||||
src/view.o \
|
||||
@ -57,13 +43,18 @@ OBJS = \
|
||||
src/file.o \
|
||||
src/pack.o \
|
||||
src/dds/validate.o \
|
||||
src/vulkan_helper.o \
|
||||
src/tga/tga.o \
|
||||
src/font/outline.o \
|
||||
src/renpy/vulkan.o \
|
||||
src/renpy/script.o \
|
||||
src/renpy/interpreter.o \
|
||||
src/renpy/interact.o
|
||||
src/vulkan_helper.o \
|
||||
src/collada/scene/vulkan.o \
|
||||
src/collada/scene/reload.o \
|
||||
src/collada/scene.o \
|
||||
src/collada/node_state.o \
|
||||
src/collada/animate.o \
|
||||
src/minecraft/world.o \
|
||||
src/minecraft/entry_table.o \
|
||||
src/minecraft/vulkan.o \
|
||||
src/minecraft/vulkan/per_world.o \
|
||||
src/font/outline.o
|
||||
|
||||
WORLDS = \
|
||||
data/minecraft/midnightmeadow/inthash.o \
|
||||
@ -92,9 +83,6 @@ all: main
|
||||
%.o: %.s
|
||||
$(AS) $< -o $@
|
||||
|
||||
#%.dds: %.png
|
||||
# WINEDEBUG=-all wine $(HOME)/Texconv.exe -y -nogpu -nowic -dx10 --format BC7_UNORM_SRGB -m 1 $< -o $(dir $@)
|
||||
|
||||
main: $(OBJS) $(LIBS) $(SCENES) $(WORLDS)
|
||||
$(CC) $(ARCH) $(LDFLAGS) $(FLAGS) $(OPT) $(DEBUG) $^ -o $@
|
||||
|
||||
|
||||
|
Before Width: | Height: | Size: 789 KiB |
|
Before Width: | Height: | Size: 1.1 MiB |
|
Before Width: | Height: | Size: 802 KiB |
|
Before Width: | Height: | Size: 272 KiB |
|
Before Width: | Height: | Size: 5.3 KiB |
|
Before Width: | Height: | Size: 126 KiB |
|
Before Width: | Height: | Size: 114 KiB |
|
Before Width: | Height: | Size: 145 KiB |
|
Before Width: | Height: | Size: 144 KiB |
|
Before Width: | Height: | Size: 20 KiB |
@ -1,541 +0,0 @@
|
||||
# The script of the game goes in this file.
|
||||
|
||||
# Declare characters used by this game. The color argument colorizes the
|
||||
# name of the character.
|
||||
image bgwhite = "#ffffff"
|
||||
image bgforest1 = "bg/forest1.png"
|
||||
image bgforest2 = "bg/forest2.png"
|
||||
image bgflower1 = "bg/flowerfield1.png"
|
||||
image bgwheatfield1 = "bg/wheatfield1.png"
|
||||
|
||||
image cat = "ch/cat.png"
|
||||
image catw = "ch/catw.png"
|
||||
image ei = "ch/Eily.png"
|
||||
image al = "ch/Alice.png"
|
||||
#image ei1 = "ch/eily1.png"
|
||||
#image al1 = "ch/alice1.png"
|
||||
|
||||
define a = Character("Alice",color="00765e")
|
||||
define c = Character("Cat",color="590093")
|
||||
define e = Character("Eily",color="0b6092")
|
||||
define mg = Character("Mouse Girls",color="000000")
|
||||
define n = Character("Narrator",color="000000")
|
||||
define l = Character("Leona",color="590093")
|
||||
|
||||
#this centers the name display
|
||||
define gui.name_xpos = 0.5
|
||||
define gui.name_xalign = 0.5
|
||||
|
||||
#this centers the dialogue display
|
||||
define gui.dialogue_xpos = 0.5
|
||||
define gui.dialogue_text_xalign = 0.5
|
||||
|
||||
transform centerleft:
|
||||
xalign 0.3
|
||||
yalign 1.0
|
||||
|
||||
|
||||
|
||||
transform centerright:
|
||||
xalign 0.7
|
||||
yalign 1.0
|
||||
|
||||
|
||||
init:
|
||||
python:
|
||||
renpy.music.register_channel("ScaredMice", "music", loop=True)
|
||||
renpy.music.register_channel("TinyForestMinstrels", "music", loop=True)
|
||||
renpy.music.register_channel("MistAmbience", "music", loop=False)
|
||||
renpy.music.register_channel("PhrygianButterflies", "music", loop=True)
|
||||
renpy.music.register_channel("WheatFields", "music", loop=True)
|
||||
|
||||
|
||||
|
||||
# The game starts here.
|
||||
|
||||
label start:
|
||||
|
||||
# Show a background. This uses a placeholder by default, but you can
|
||||
# add a file (named either "bg room.png" or "bg room.jpg") to the
|
||||
# images directory to show it.
|
||||
|
||||
#play Chime "sfx/Chime.ogg" fadeout 1.0
|
||||
play sound "sfx/Chime.ogg"
|
||||
play MistAmbience "sfx/MistAmbience.ogg"
|
||||
scene bgwhite
|
||||
with Dissolve(3.0)
|
||||
#play music "IntroMusicTest.ogg"
|
||||
|
||||
#play NarratorLoop "n1test.mp3"
|
||||
#voice "n1test.mp3"
|
||||
n "Far over the mountains of Almystice"
|
||||
#voice "n2test.mp3"
|
||||
n "Beyond the tumultuous waters of the Lilac Bay"
|
||||
#voice "n3test.mp3"
|
||||
n "And across the vast fields of Alysen"
|
||||
#voice "n4test.mp3"
|
||||
play TinyForestMinstrels "music/TinyForestMinstrels.ogg"
|
||||
n "Tiny minstrels can be heard amongst the trees"
|
||||
|
||||
|
||||
scene bgforest1
|
||||
with Dissolve(3.0)
|
||||
|
||||
show al at left
|
||||
a "Are we almost there?"
|
||||
|
||||
show ei at right
|
||||
|
||||
e "Hmmm... Not really"
|
||||
|
||||
a "How much further have we to go?"
|
||||
|
||||
e "About two more moons"
|
||||
|
||||
menu:
|
||||
"Complain" :
|
||||
|
||||
a "We are still sooo far awayyy"
|
||||
|
||||
e "And it will be even further if you dont stop complaining"
|
||||
|
||||
a "Easy for you to say, all you have to carry is a little memory pipe!"
|
||||
a "I'm tired ><"
|
||||
|
||||
e "Don't start whining now!"
|
||||
|
||||
e "You need to remember why we have come all this way"
|
||||
|
||||
a "I understand... I suppose it is for an important purpose"
|
||||
|
||||
"Rationalize" :
|
||||
|
||||
a "I understand... I suppose it is for an important purpose"
|
||||
jump mainbranch1
|
||||
|
||||
|
||||
label mainbranch1:
|
||||
e "We're almost out of the forest, we can take a little break once we clear the tree line"
|
||||
|
||||
a "Is that where the flora field is?"
|
||||
|
||||
e "Why yes, If I remember correctly, it should be just up ahead"
|
||||
stop TinyForestMinstrels fadeout 5.5
|
||||
|
||||
scene bgwhite
|
||||
play sound "sfx/Chime.ogg"
|
||||
with Dissolve(1.0)
|
||||
|
||||
|
||||
voice "n5test.ogg"
|
||||
n "As the minstrel mice girls continue along the path, the forest opens up into a beautiful field of flowers"
|
||||
|
||||
play PhrygianButterflies "music/PhrygianButterflies.ogg"
|
||||
|
||||
|
||||
scene bgflower1
|
||||
with Dissolve(1.0)
|
||||
|
||||
show ei at right
|
||||
|
||||
e "Look at all the butterflies! They are all so pretty!"
|
||||
|
||||
show al at left
|
||||
|
||||
|
||||
a "This place is like a dream..."
|
||||
|
||||
e "There are so many flowers this time of year"
|
||||
e "I told you it would be worth the journey!"
|
||||
|
||||
a "Can we stop for a bit now?"
|
||||
|
||||
e "Of course"
|
||||
e "Ya know, Its a shame we didnt save some of those giant strawberries you found"
|
||||
|
||||
a "I told you not to eat them all!"
|
||||
|
||||
e "Yah yah"
|
||||
e "Anyways, shall I recite a tale?"
|
||||
|
||||
menu:
|
||||
|
||||
|
||||
"Good idea" :
|
||||
stop PhrygianButterflies fadeout 4.2
|
||||
a "Why dont you sing the story of Eleanor the Hero!"
|
||||
e "Sure"
|
||||
a "..."
|
||||
play music "music/Poem1.ogg" noloop
|
||||
pause 40
|
||||
"I am too tired" :
|
||||
e "Serves you right for scaring those elephant-dogs"
|
||||
stop PhrygianButterflies fadeout 4.2
|
||||
a "They were asking for it, you know"
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
jump mainbranch2
|
||||
|
||||
#Improvise music in the butterfly field
|
||||
#Choose Between: Fleeting and
|
||||
#Elri scares the mice
|
||||
#We learn why they want to petition the queen
|
||||
# elri: "Arent you sacred she will eat you?"
|
||||
# elri: "Also, why would two little mice"
|
||||
#Elri shows them to the wheat town with the castle in the distance
|
||||
#They wish to speak to the queen of birds, but arent important enough
|
||||
#Elri helps
|
||||
|
||||
|
||||
|
||||
|
||||
#Cat is summoned to see the Queen of birds
|
||||
|
||||
#Mouse girls realize its their only chance
|
||||
|
||||
|
||||
#
|
||||
|
||||
#Lenient on Taxes
|
||||
#Removed from the map
|
||||
|
||||
#And what is this? A cat and 2 mice stumbling about into my courtroom?
|
||||
#
|
||||
#
|
||||
label mainbranch2:
|
||||
hide ei
|
||||
show catw at right
|
||||
show ei at centerleft:
|
||||
xzoom -1
|
||||
voice "placeholdermeow.mp3"
|
||||
c "Rawrrrr"
|
||||
hide catw
|
||||
show cat at right
|
||||
play ScaredMice "music/ScaredMice.ogg"
|
||||
|
||||
|
||||
mg "AHHHHHHHHHH!!!!!"
|
||||
|
||||
|
||||
c "Nyanyanyanya"
|
||||
c "Well, what do we have here? If it isn't two little meowse girls, all alone amongst the flowers"
|
||||
|
||||
menu:
|
||||
"Beg for mercy" :
|
||||
a "Please don't eat us!!!"
|
||||
|
||||
"Run" :
|
||||
e "Alice don't run, our only chance is through pleading!"
|
||||
e "Please don't eat us, miss kitty cat!!! ><"
|
||||
|
||||
|
||||
|
||||
jump mainbranch3
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
label mainbranch3:
|
||||
stop ScaredMice fadeout 2.0
|
||||
c "I'm not gonna eat you nyanyanya"
|
||||
play TinyForestMinstrels "music/TinyForestMinstrels.ogg"
|
||||
c "I just want to know what two little meowses are doing so very far away from home"
|
||||
c "Also, are you minstrels?"
|
||||
|
||||
e "Y-Yes"
|
||||
a "W-We are on a quest to Castle Alysen..."
|
||||
e "Shh don't tell her that"
|
||||
|
||||
c "The Castle of Alysen you say?!?"
|
||||
c "Why, that's where I am headed!"
|
||||
|
||||
e "You don't say..."
|
||||
|
||||
c "Yah, I do actually"
|
||||
|
||||
e "So... Why might you be traveling to the castle?"
|
||||
|
||||
c "I belong to the lineage of Agrepen"
|
||||
|
||||
e "And what might that mean?"
|
||||
|
||||
c "The Agrepens are a long line of felines loyal to the crown of corvidae"
|
||||
|
||||
e "Really? That must mean you are a noble?"
|
||||
|
||||
c "Well, not really..."
|
||||
c "My father was one of the queens knights many years ago"
|
||||
|
||||
e "Ah I see"
|
||||
|
||||
e "So do you live at the castle or something?"
|
||||
|
||||
c "Well, no..."
|
||||
|
||||
a "Then why are you traveling to Castle Alysen?"
|
||||
|
||||
|
||||
c "uhhh"
|
||||
play MistAmbience "sfx/MistAmbience.ogg"
|
||||
stop TinyForestMinstrels fadeout 2.0
|
||||
c "I DONT NEED TO BE PRESSURED BY LITTLE MICE TO SAY ANYTHING!!!!"
|
||||
c "GOOD DAY!"
|
||||
|
||||
hide cat
|
||||
|
||||
a "Wha..."
|
||||
|
||||
e "Phew, I was scared she was gonna follow us the whole way"
|
||||
|
||||
a "She didn't seem so bad"
|
||||
#play MistAmbience "sfx/MistAmbience.ogg"
|
||||
|
||||
e "Are you kidding? She's a crazy kitty!"
|
||||
|
||||
scene bgwhite
|
||||
play sound "sfx/Chime.ogg"
|
||||
with Dissolve(3.0)
|
||||
|
||||
n "After their encounter with the weird cat, the mice scurry out of the flower field and into the nearby meadow"
|
||||
scene bgforest2
|
||||
with Dissolve(3.0)
|
||||
|
||||
show ei at right
|
||||
e "I think this is the right way..."
|
||||
show al at left
|
||||
a "Then where did the path go?"
|
||||
|
||||
e "How am I supposed to know?"
|
||||
|
||||
|
||||
a "Did you hear that?!?!"
|
||||
|
||||
show ei at centerleft:
|
||||
xzoom -1
|
||||
|
||||
show cat at right
|
||||
play PhrygianButterflies "music/PhrygianButterflies.ogg"
|
||||
c "Hey there..."
|
||||
c "I apologize"
|
||||
c "I didn't mean to storm off like that"
|
||||
|
||||
e "Ha ha, no problem..."
|
||||
|
||||
a "So... Why are you traveling to Castle Alysen?"
|
||||
|
||||
e "Alice!!!"
|
||||
|
||||
c "If you must know, I have been summoned by the queen"
|
||||
c "I suspect that my poor reputation amongst the locals of Eastern Nidus has come back to haunt me"
|
||||
c "Though I know not what what she has summoned me for"
|
||||
|
||||
a "Ahhhhhh"
|
||||
|
||||
c "So then..."
|
||||
c "Why are YOU traveling to the Castle?"
|
||||
|
||||
a "We are delivering a feather!!!"
|
||||
|
||||
e "Alice no!"
|
||||
|
||||
a "A feather that belonged to the queen herself!!!"
|
||||
|
||||
e "Why you little..."
|
||||
|
||||
c "A feather you say? One of the queens?"
|
||||
c "How on the face of Al Mot might you have aquired such a thing?"
|
||||
c "If it is authentic, that is..."
|
||||
|
||||
e "Since Alice cannot keep a secret, I shall tell you"
|
||||
e "Seven moons ago, our town was attacked by three owls and a band of mice from the northern principalities"
|
||||
e "Eventually word spread to greater nearby settlements, and so"
|
||||
e "Messengers from the keep in Musia sent for aid from the Ravens"
|
||||
e "Four moons ago, the request was answered"
|
||||
e "And a small group of mice accompanied by two ravens a fox, and three squirrels set out to the northern principalities"
|
||||
e "Anyways, long story short, we drove those barbaric rats out of their home"
|
||||
|
||||
a "They arent actual rats you know"
|
||||
|
||||
e "Obviously, but you wont catch me speaking kindly of them"
|
||||
|
||||
a "And you forgot the most important part"
|
||||
|
||||
e "Yah yah, I am getting there"
|
||||
e "So, essentially, my brother is trained in archery, and..."
|
||||
|
||||
a "Speed it up already"
|
||||
|
||||
e "You tell it then!"
|
||||
|
||||
a "My cousin found this feather in one of the highest towers of a castle far to the north"
|
||||
|
||||
c "How do you know it belongs to the queen?"
|
||||
|
||||
e "It said so itself above the display on the wall"
|
||||
|
||||
a "Supposedly, it was in a room filled with treasures!"
|
||||
|
||||
c "That is very nice and all, but what are the two of you doing out here all alone?"
|
||||
|
||||
c "Do you expect every bird in Avia to respect your alliance with Castle Alysen?"
|
||||
|
||||
e "What do you mean?"
|
||||
|
||||
c "I mean, the two of you probably look like walking dinner to most creatures"
|
||||
|
||||
a "I could go for some dinner..."
|
||||
e "Anyways..."
|
||||
e "To answer your question, upon returning to the village, the feather was taken from my brother by the needle guild"
|
||||
e "So... Yesterday, after sundown"
|
||||
e "We stole the feather from the guild hall before vanishing into the night"
|
||||
|
||||
e "Can you imagine the look on their stupid faces, when they woke up, and not only is the feather missing"
|
||||
|
||||
e "But so are we!"
|
||||
|
||||
a "Hahahaha"
|
||||
|
||||
c "Are the two of you mad?"
|
||||
c "I assume you are attempting to return the Queens feather?"
|
||||
|
||||
a "Yes, we intend to deliver the feather to its rightful owner"
|
||||
|
||||
c "Absolute madness!"
|
||||
|
||||
mg "..."
|
||||
|
||||
|
||||
c "I will follow the two of you"
|
||||
c "To keep you safe, that is"
|
||||
|
||||
a "Alright!"
|
||||
|
||||
e "Ha ha... Okay..."
|
||||
|
||||
c "Great! Follow me, I know a shortcut! :3"
|
||||
|
||||
hide cat
|
||||
|
||||
a "Sounds good!"
|
||||
|
||||
hide al
|
||||
stop PhrygianButterflies fadeout 2.0
|
||||
|
||||
|
||||
e "Oh dear!"
|
||||
hide ei
|
||||
|
||||
#hide al
|
||||
#hide ei
|
||||
|
||||
|
||||
|
||||
#pause 10
|
||||
scene bgwhite
|
||||
play sound "sfx/Chime.ogg"
|
||||
with Dissolve(2.0)
|
||||
n "And so the mice girls follow the noble cat further towards their destination"
|
||||
|
||||
scene bgwheatfield1
|
||||
play WheatFields "music/WheatFields.ogg"
|
||||
show cat at right
|
||||
with Dissolve(1.3)
|
||||
c "Nya"
|
||||
show al at left
|
||||
a "Look, your right, the castle is just up ahead!"
|
||||
show ei at centerleft:
|
||||
xzoom -1
|
||||
e "Wait up"
|
||||
|
||||
c "I told you I knew a shortcut!"
|
||||
c "Most people take the long way around"
|
||||
|
||||
e "Yah because these are royal wheatfields!"
|
||||
a "Who cares?"
|
||||
e "Are you trying to get us killed?"
|
||||
e "Its trespassing on royal land!"
|
||||
|
||||
c "Calm down, I have done this a million times"
|
||||
|
||||
e "That doesnt make me calm!"
|
||||
|
||||
c "How can the rolling fields of wheat not calm your spirit?"
|
||||
c "You little mice truly are mad!"
|
||||
|
||||
a "I like the wheat!"
|
||||
|
||||
e "Shut up!"
|
||||
|
||||
c "Sounds like someone needs a nap!"
|
||||
|
||||
e "Why? because I'm not insane like you?"
|
||||
|
||||
c "Yah, your so sane, that you decided to steal from your town and then run off alone to the country of birds"
|
||||
c "The power of friendship wont protect the two of you from becoming dinner"
|
||||
c "And that, is why I feel obligated to accompany you!"
|
||||
|
||||
e "Hey, we have a good reason!"
|
||||
|
||||
c "And what might that be?"
|
||||
|
||||
e "My brother found the feather, not the town guild, its a matter of family pride!"
|
||||
|
||||
c "Pride has touched the chosen meouse"
|
||||
c "Flies she towards the Castle"
|
||||
c "But her ambition burns far too bright, and silly myice dont have any wings to myelt"
|
||||
|
||||
mg "What?"
|
||||
|
||||
c "Nyanyanya"
|
||||
c "Nyevermind"
|
||||
c "Sing me a song little minstrels!"
|
||||
|
||||
c "Very Nyice!"
|
||||
c "Now tell me little minstrels, what are your names?"
|
||||
|
||||
a "My name is Alice"
|
||||
e "And my name is Eily"
|
||||
e "What is your name?"
|
||||
|
||||
l "My name is Leona!"
|
||||
|
||||
scene bgwhite
|
||||
with Dissolve(3.0)
|
||||
|
||||
n "And so, the odd trio walked through the wheatfields and towards the castle walls"
|
||||
n "Upon approaching the castle walls"
|
||||
|
||||
|
||||
|
||||
|
||||
# birds!!!
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
return
|
||||
@ -1,13 +1,40 @@
|
||||
shader/font.spv
|
||||
data/font/outline/medieval_sharp_24.data
|
||||
shader/collada.spv
|
||||
data/scenes/shadow_test/shadow_test.vtx
|
||||
data/scenes/shadow_test/shadow_test.idx
|
||||
data/scenes/shadow_test/images/0_leaf_white.dds
|
||||
|
||||
shader/renpy.spv
|
||||
data/renpy/images/flowers.dds
|
||||
data/renpy/images/bg/forest1.dds
|
||||
data/renpy/images/bg/forest2.dds
|
||||
data/renpy/images/bg/flowerfield1.dds
|
||||
data/renpy/images/bg/wheatfield1.dds
|
||||
data/renpy/images/ch/cat.dds
|
||||
data/renpy/images/ch/catw.dds
|
||||
data/renpy/images/ch/Eily.dds
|
||||
data/renpy/images/ch/Alice.dds
|
||||
data/scenes/eidelwind/eidelwind.vtx
|
||||
data/scenes/eidelwind/eidelwind.vjw
|
||||
data/scenes/eidelwind/eidelwind.idx
|
||||
data/scenes/eidelwind/images/0_EidelWindTextureTest.dds
|
||||
|
||||
shader/minecraft.spv
|
||||
data/minecraft/per_vertex.vtx
|
||||
data/minecraft/configuration.idx
|
||||
|
||||
data/minecraft/grandlecturn/region.0.0.instance.vtx
|
||||
data/minecraft/grandlecturn/region.-1.0.instance.vtx
|
||||
data/minecraft/grandlecturn/region.0.-1.instance.vtx
|
||||
data/minecraft/grandlecturn/region.-1.-1.instance.vtx
|
||||
data/minecraft/grandlecturn/region.0.0.instance.cfg
|
||||
data/minecraft/grandlecturn/region.-1.0.instance.cfg
|
||||
data/minecraft/grandlecturn/region.0.-1.instance.cfg
|
||||
data/minecraft/grandlecturn/region.-1.-1.instance.cfg
|
||||
data/minecraft/grandlecturn/global.dump
|
||||
data/minecraft/grandlecturn/global.lights.vtx
|
||||
|
||||
data/minecraft/midnightmeadow/region.0.0.instance.vtx
|
||||
data/minecraft/midnightmeadow/region.-1.0.instance.vtx
|
||||
data/minecraft/midnightmeadow/region.0.-1.instance.vtx
|
||||
data/minecraft/midnightmeadow/region.-1.-1.instance.vtx
|
||||
data/minecraft/midnightmeadow/region.0.0.instance.cfg
|
||||
data/minecraft/midnightmeadow/region.-1.0.instance.cfg
|
||||
data/minecraft/midnightmeadow/region.0.-1.instance.cfg
|
||||
data/minecraft/midnightmeadow/region.-1.-1.instance.cfg
|
||||
data/minecraft/midnightmeadow/global.dump
|
||||
data/minecraft/midnightmeadow/global.lights.vtx
|
||||
|
||||
data/minecraft/terrain2.dds
|
||||
|
||||
shader/font.spv
|
||||
data/font/outline/uncial_antiqua_36.data
|
||||
|
||||
1
font.sh
@ -1 +0,0 @@
|
||||
~/dreamcast/tools/ttf_outline 20 7f 24 0 little ~/mouse2/mousegirl4/game/fonts/MedievalSharp-Regular.ttf ~/vulkan/data/font/outline/medieval_sharp_24.data
|
||||
@ -2,7 +2,6 @@
|
||||
|
||||
#include "outline_types.h"
|
||||
#include "vulkan_helper.h"
|
||||
#include "renpy/interpreter.h"
|
||||
|
||||
namespace font::outline {
|
||||
|
||||
@ -10,15 +9,12 @@ namespace font::outline {
|
||||
char const * const path;
|
||||
};
|
||||
|
||||
font_desc const medieval_sharp[] = {
|
||||
font_desc const uncial_antiqua[] = {
|
||||
{
|
||||
.path = "data/font/outline/medieval_sharp_24.data",
|
||||
.path = "data/font/outline/uncial_antiqua_36.data",
|
||||
},
|
||||
};
|
||||
int const medieval_sharp_length = (sizeof (medieval_sharp)) / (sizeof (font_desc));
|
||||
|
||||
constexpr uint32_t textboxLeft = 410;
|
||||
constexpr uint32_t textboxWidth = 450;
|
||||
int const uncial_antiqua_length = (sizeof (uncial_antiqua)) / (sizeof (font_desc));
|
||||
|
||||
struct AllocatedImage {
|
||||
VkImage image;
|
||||
@ -104,21 +100,8 @@ namespace font::outline {
|
||||
void create_instance_buffers();
|
||||
void create_pipeline();
|
||||
void create_glyphs_buffer(types::font const * const font, types::glyph const * const glyphs);
|
||||
void emit_line(int frameIndex,
|
||||
char const * const string,
|
||||
uint32_t x, uint32_t y,
|
||||
int& outputIndex,
|
||||
int startIndex,
|
||||
int endIndex,
|
||||
uint32_t color);
|
||||
void centered(int frameIndex, char const * const string, uint32_t& x, uint32_t& y,
|
||||
uint32_t minX,
|
||||
uint32_t maxWidth,
|
||||
int& outputIndex,
|
||||
uint32_t color);
|
||||
void draw(VkCommandBuffer commandBuffer,
|
||||
uint32_t frameIndex,
|
||||
renpy::interpreter const& state);
|
||||
uint32_t frameIndex);
|
||||
|
||||
LoadedFont load_font(font_desc const& desc);
|
||||
};
|
||||
|
||||
@ -1,17 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
#include "renpy/interpreter.h"
|
||||
|
||||
namespace renpy {
|
||||
|
||||
namespace menu {
|
||||
constexpr int width = 480;
|
||||
constexpr int height = 40;
|
||||
constexpr int x = 400;
|
||||
constexpr int y = 100;
|
||||
constexpr int yStride = 100;
|
||||
};
|
||||
|
||||
bool overlap(int width, int height, int x, int y, int mx, int my);
|
||||
void update(interpreter & state, int mx, int my, bool mLeft);
|
||||
}
|
||||
@ -1,52 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#include "renpy/language.h"
|
||||
|
||||
namespace renpy {
|
||||
struct top_left {
|
||||
uint32_t top;
|
||||
uint32_t left;
|
||||
};
|
||||
|
||||
static constexpr top_left transforms[] = {
|
||||
[language::transform::left] = { .top = 192, .left = 0 },
|
||||
[language::transform::centerleft] = { .top = 192, .left = 240 },
|
||||
[language::transform::center] = { .top = 192, .left = 416 },
|
||||
[language::transform::centerright] = { .top = 192, .left = 588 },
|
||||
[language::transform::right] = { .top = 192, .left = 828 },
|
||||
};
|
||||
static constexpr int transformsCount = (sizeof (transforms)) / (sizeof (transforms[0]));
|
||||
|
||||
struct shownImage {
|
||||
uint32_t imageIndex;
|
||||
uint32_t transformIndex;
|
||||
};
|
||||
|
||||
static constexpr int maximumShownImagesCount = 16;
|
||||
|
||||
struct interpreter {
|
||||
uint32_t pc;
|
||||
uint32_t backgroundIndex;
|
||||
uint32_t backgroundColor;
|
||||
shownImage shownImages[maximumShownImagesCount];
|
||||
uint32_t shownImagesCount;
|
||||
struct {
|
||||
uint32_t stringIndex;
|
||||
uint32_t characterIndex;
|
||||
} say;
|
||||
struct {
|
||||
uint32_t count;
|
||||
uint32_t optionIndex;
|
||||
} menu;
|
||||
bool interactionWait;
|
||||
|
||||
uint32_t findImage(uint32_t imageIndex);
|
||||
void showImage(uint32_t imageIndex, uint32_t transformIndex);
|
||||
void hideImage(uint32_t imageIndex);
|
||||
void reset();
|
||||
void interpret_one();
|
||||
void interpret();
|
||||
};
|
||||
}
|
||||
@ -1,22 +0,0 @@
|
||||
#include "renpy/language.h"
|
||||
|
||||
namespace renpy::script {
|
||||
extern char const * const strings[];
|
||||
extern const int strings_length;
|
||||
|
||||
extern const language::character characters[];
|
||||
extern const int characters_length;
|
||||
|
||||
extern const language::audio audio[];
|
||||
extern const int audio_length;
|
||||
|
||||
extern const language::image images[];
|
||||
extern const int images_length;
|
||||
|
||||
extern const language::option options[];
|
||||
extern const int options_length;
|
||||
|
||||
extern const language::statement statements[];
|
||||
extern const int statements_length;
|
||||
|
||||
}
|
||||
@ -1,90 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
#include "renpy/interpreter.h"
|
||||
|
||||
namespace renpy {
|
||||
struct Image {
|
||||
VkImage image;
|
||||
VkDeviceMemory memory;
|
||||
VkImageView imageView;
|
||||
};
|
||||
|
||||
struct ImageInstance {
|
||||
struct {
|
||||
int16_t width;
|
||||
int16_t height;
|
||||
} size;
|
||||
struct {
|
||||
int16_t x;
|
||||
int16_t y;
|
||||
} topLeft;
|
||||
uint32_t color;
|
||||
int16_t imageIndex;
|
||||
int16_t _padding;
|
||||
};
|
||||
|
||||
static_assert((sizeof (ImageInstance)) == 16);
|
||||
|
||||
struct vulkan {
|
||||
static constexpr int perVertexSize = (4) * 2;
|
||||
static constexpr int perInstanceSize = (sizeof (ImageInstance));
|
||||
static constexpr int maximumImageCount = 16;
|
||||
|
||||
// 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;
|
||||
|
||||
VkDeviceSize instanceBufferOffset[2];
|
||||
VkBuffer instanceBuffer;
|
||||
VkDeviceMemory instanceMemory;
|
||||
VkDeviceSize instanceMemorySize;
|
||||
ImageInstance * instanceMappedData;
|
||||
|
||||
VkDescriptorPool descriptorPool{ VK_NULL_HANDLE };
|
||||
static constexpr int descriptorSetLayoutCount = 1;
|
||||
VkDescriptorSetLayout descriptorSetLayouts[descriptorSetLayoutCount]; // unrelated to maxFrames, unrelated to descriptorCount
|
||||
VkDescriptorSet descriptorSet0;
|
||||
|
||||
Image * images;
|
||||
|
||||
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();
|
||||
void load_image_inner(VkCommandBuffer commandBuffer, VkFence fence, int i, char const * filename);
|
||||
void load_images();
|
||||
void create_pipeline();
|
||||
void create_instance_buffers();
|
||||
void draw(VkCommandBuffer commandBuffer,
|
||||
uint32_t frameIndex,
|
||||
renpy::interpreter const& state,
|
||||
int mx,
|
||||
int my);
|
||||
|
||||
};
|
||||
}
|
||||
@ -1,18 +1,6 @@
|
||||
#pragma once
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
namespace renpy::language {
|
||||
struct transform {
|
||||
enum _transform {
|
||||
left,
|
||||
centerleft,
|
||||
center,
|
||||
centerright,
|
||||
right,
|
||||
};
|
||||
};
|
||||
|
||||
namespace language {
|
||||
struct option {
|
||||
char const * const string;
|
||||
uint32_t statementIndex;
|
||||
@ -20,7 +8,6 @@ namespace renpy::language {
|
||||
|
||||
struct character {
|
||||
char const * const characterName;
|
||||
uint32_t color;
|
||||
};
|
||||
|
||||
struct audio {
|
||||
@ -40,14 +27,9 @@ namespace renpy::language {
|
||||
_return,
|
||||
say,
|
||||
scene,
|
||||
scene_color,
|
||||
show,
|
||||
voice,
|
||||
with,
|
||||
stop,
|
||||
pause,
|
||||
hide,
|
||||
dissolve,
|
||||
};
|
||||
|
||||
struct jump {
|
||||
@ -76,10 +58,6 @@ namespace renpy::language {
|
||||
uint32_t imageIndex;
|
||||
};
|
||||
|
||||
struct scene_color {
|
||||
uint32_t color;
|
||||
};
|
||||
|
||||
struct show {
|
||||
uint32_t imageIndex;
|
||||
uint32_t transformIndex;
|
||||
@ -92,37 +70,16 @@ namespace renpy::language {
|
||||
struct with {
|
||||
};
|
||||
|
||||
struct stop {
|
||||
uint32_t channelIndex;
|
||||
};
|
||||
|
||||
struct pause {
|
||||
float duration;
|
||||
};
|
||||
|
||||
struct hide {
|
||||
uint32_t imageIndex;
|
||||
};
|
||||
|
||||
struct dissolve {
|
||||
float duration;
|
||||
};
|
||||
|
||||
struct statement {
|
||||
enum type type;
|
||||
union {
|
||||
renpy::language::jump jump;
|
||||
renpy::language::menu menu;
|
||||
renpy::language::play play;
|
||||
renpy::language::say say;
|
||||
renpy::language::scene scene;
|
||||
renpy::language::scene_color scene_color;
|
||||
renpy::language::show show;
|
||||
renpy::language::voice voice;
|
||||
renpy::language::stop stop;
|
||||
renpy::language::pause pause;
|
||||
renpy::language::hide hide;
|
||||
renpy::language::dissolve dissolve;
|
||||
jump jump;
|
||||
menu menu;
|
||||
play play;
|
||||
say say;
|
||||
scene scene;
|
||||
show show;
|
||||
voice voice;
|
||||
};
|
||||
};
|
||||
}
|
||||
@ -45,11 +45,6 @@ class TT(Enum):
|
||||
RETURN = auto()
|
||||
INIT = auto()
|
||||
FADEOUT = auto()
|
||||
TRANSFORM = auto()
|
||||
STOP = auto()
|
||||
NOLOOP = auto()
|
||||
PAUSE = auto()
|
||||
HIDE = auto()
|
||||
|
||||
keywords = {
|
||||
b"play": TT.PLAY,
|
||||
@ -66,11 +61,6 @@ keywords = {
|
||||
b"return": TT.RETURN,
|
||||
b"init": TT.INIT,
|
||||
b"fadeout": TT.FADEOUT,
|
||||
b"transform": TT.TRANSFORM,
|
||||
b"stop": TT.STOP,
|
||||
b"noloop": TT.NOLOOP,
|
||||
b"pause": TT.PAUSE,
|
||||
b"hide": TT.HIDE,
|
||||
}
|
||||
|
||||
@dataclass
|
||||
|
||||
@ -56,14 +56,6 @@ class Play:
|
||||
channel: lex.Token
|
||||
path: lex.Token
|
||||
fadeout: lex.Token
|
||||
noloop: bool
|
||||
|
||||
__repr__ = lexeme_repr
|
||||
|
||||
@dataclass
|
||||
class Stop:
|
||||
channel: lex.Token
|
||||
fadeout: lex.Token
|
||||
|
||||
__repr__ = lexeme_repr
|
||||
|
||||
@ -96,7 +88,6 @@ class Voice:
|
||||
class Show:
|
||||
what: lex.Token
|
||||
transform: lex.Token
|
||||
properties: list[tuple[lex.Token, lex.Token]]
|
||||
|
||||
__repr__ = lexeme_repr
|
||||
|
||||
@ -111,18 +102,6 @@ class Jump:
|
||||
|
||||
__repr__ = lexeme_repr
|
||||
|
||||
@dataclass
|
||||
class Pause:
|
||||
duration: lex.Token
|
||||
|
||||
__repr__ = lexeme_repr
|
||||
|
||||
@dataclass
|
||||
class Hide:
|
||||
what: lex.Token
|
||||
|
||||
__repr__ = lexeme_repr
|
||||
|
||||
@dataclass
|
||||
class Return:
|
||||
pass
|
||||
@ -263,16 +242,11 @@ def parse_play(tokens, index):
|
||||
if fadeout.type != TT.NUMBER:
|
||||
raise ParseException("expected number", fadeout)
|
||||
index += 2
|
||||
noloop = False
|
||||
if token.type == TT.NOLOOP:
|
||||
noloop = True
|
||||
index += 1
|
||||
|
||||
play = Play(
|
||||
channel = channel,
|
||||
path = path,
|
||||
fadeout = fadeout,
|
||||
noloop = noloop,
|
||||
fadeout = fadeout
|
||||
)
|
||||
return index, play
|
||||
|
||||
@ -316,12 +290,6 @@ def parse_voice(tokens, index):
|
||||
return index + 1, voice
|
||||
|
||||
def parse_show(tokens, index):
|
||||
show = tokens[index + 0]
|
||||
if show.type != TT.SHOW:
|
||||
raise ParseException("expected show", show)
|
||||
|
||||
index += 1
|
||||
|
||||
index, what = parse_lhs(tokens, index)
|
||||
|
||||
at = tokens[index + 0]
|
||||
@ -332,36 +300,11 @@ def parse_show(tokens, index):
|
||||
if transform.type != TT.IDENTIFIER:
|
||||
raise ParseException("expected identifier", transform)
|
||||
|
||||
index += 2
|
||||
|
||||
properties = []
|
||||
if tokens[index + 0].type == TT.COLON:
|
||||
index += 1
|
||||
while index < len(tokens):
|
||||
token = tokens[index + 0]
|
||||
if token.type == TT.NEWLINE:
|
||||
index += 1
|
||||
continue
|
||||
|
||||
if token.position.column <= show.position.column:
|
||||
break
|
||||
|
||||
if token.type != TT.IDENTIFIER:
|
||||
raise ParseException("expected identifier")
|
||||
|
||||
number = tokens[index + 1]
|
||||
if number.type != TT.NUMBER:
|
||||
raise ParseException("expected number")
|
||||
|
||||
properties.append((token, number))
|
||||
index += 2
|
||||
|
||||
show = Show(
|
||||
what = what,
|
||||
transform = transform,
|
||||
properties = properties
|
||||
transform = transform
|
||||
)
|
||||
return index, show
|
||||
return index + 2, show
|
||||
|
||||
def parse_menu(tokens, index):
|
||||
menu = tokens[index + 0]
|
||||
@ -426,7 +369,7 @@ def parse_init(tokens, index):
|
||||
|
||||
colon = tokens[index + 1]
|
||||
if colon.type != TT.COLON:
|
||||
raise ParseException("expected colon", colon)
|
||||
raise ParseException("expected identifier", colon)
|
||||
|
||||
index += 2
|
||||
|
||||
@ -445,74 +388,6 @@ def parse_init(tokens, index):
|
||||
|
||||
return index, None
|
||||
|
||||
def parse_transform(tokens, index):
|
||||
transform = tokens[index + 0]
|
||||
if transform.type != TT.TRANSFORM:
|
||||
raise ParseException("expected transform", init)
|
||||
|
||||
identifier = tokens[index + 1]
|
||||
if identifier.type != TT.IDENTIFIER:
|
||||
raise ParseException("expected identifier", identifier)
|
||||
|
||||
colon = tokens[index + 2]
|
||||
if colon.type != TT.COLON:
|
||||
raise ParseException("expected colon", colon)
|
||||
|
||||
index += 3
|
||||
|
||||
# skip all tokens inside block
|
||||
while index < len(tokens):
|
||||
token = tokens[index]
|
||||
if token.type == TT.NEWLINE:
|
||||
index += 1
|
||||
continue
|
||||
|
||||
if token.position.column < transform.position.column:
|
||||
raise ParseException("invalid init block dedent", token)
|
||||
if token.position.column == transform.position.column:
|
||||
break
|
||||
index += 1
|
||||
|
||||
return index, None
|
||||
|
||||
def parse_stop(tokens, index):
|
||||
channel = tokens[index + 0]
|
||||
if channel.type != TT.IDENTIFIER:
|
||||
raise ParseException("expected identifier", channel)
|
||||
|
||||
index += 1
|
||||
token = tokens[index]
|
||||
fadeout = None
|
||||
if token.type == TT.FADEOUT:
|
||||
fadeout = tokens[index + 1]
|
||||
if fadeout.type != TT.NUMBER:
|
||||
raise ParseException("expected number", fadeout)
|
||||
index += 2
|
||||
|
||||
stop = Stop(
|
||||
channel = channel,
|
||||
fadeout = fadeout
|
||||
)
|
||||
return index, stop
|
||||
|
||||
def parse_pause(tokens, index):
|
||||
duration = tokens[index + 0]
|
||||
if duration.type != TT.NUMBER:
|
||||
raise ParseException("expected number", duration)
|
||||
|
||||
pause = Pause(
|
||||
duration = duration
|
||||
)
|
||||
return index + 1, pause
|
||||
|
||||
def parse_hide(tokens, index):
|
||||
index, what = parse_lhs(tokens, index)
|
||||
|
||||
hide = Hide(
|
||||
what = what
|
||||
)
|
||||
return index + 1, hide
|
||||
|
||||
def parse_one(tokens, index):
|
||||
token = tokens[index]
|
||||
if token.type == TT.NEWLINE:
|
||||
@ -546,7 +421,7 @@ def parse_one(tokens, index):
|
||||
index, ast = parse_voice(tokens, index + 1)
|
||||
return index, ast
|
||||
elif token.type == TT.SHOW:
|
||||
index, ast = parse_show(tokens, index)
|
||||
index, ast = parse_show(tokens, index + 1)
|
||||
return index, ast
|
||||
elif token.type == TT.MENU:
|
||||
index, ast = parse_menu(tokens, index)
|
||||
@ -559,18 +434,6 @@ def parse_one(tokens, index):
|
||||
elif token.type == TT.INIT:
|
||||
index, ast = parse_init(tokens, index)
|
||||
return index, ast
|
||||
elif token.type == TT.TRANSFORM:
|
||||
index, ast = parse_transform(tokens, index)
|
||||
return index, ast
|
||||
elif token.type == TT.STOP:
|
||||
index, ast = parse_stop(tokens, index + 1)
|
||||
return index, ast
|
||||
elif token.type == TT.PAUSE:
|
||||
index, ast = parse_pause(tokens, index + 1)
|
||||
return index, ast
|
||||
elif token.type == TT.HIDE:
|
||||
index, ast = parse_hide(tokens, index + 1)
|
||||
return index, ast
|
||||
else:
|
||||
raise ParseException("unexpected token", token)
|
||||
|
||||
|
||||
@ -3,20 +3,17 @@ import lex
|
||||
import parse
|
||||
from dataclasses import dataclass
|
||||
from pprint import pprint
|
||||
from itertools import chain
|
||||
import generate
|
||||
|
||||
@dataclass
|
||||
class State:
|
||||
images: list
|
||||
colors: list
|
||||
characters: list
|
||||
statements: list
|
||||
menus: list
|
||||
entries: dict
|
||||
|
||||
images_lookup: dict[str, int] # identifier to image index
|
||||
colors_lookup: dict[str, int] # identifier to image index
|
||||
characters_lookup: dict[str, int] # identifier to character index
|
||||
labels_lookup: dict[str, int] # identifier to statement index
|
||||
audio_lookup: dict[str, int]
|
||||
@ -46,9 +43,6 @@ simple_statement_types = {
|
||||
parse.Show,
|
||||
parse.Voice,
|
||||
parse.With,
|
||||
parse.Stop,
|
||||
parse.Pause,
|
||||
parse.Hide,
|
||||
}
|
||||
|
||||
def pass1(state, ast):
|
||||
@ -56,12 +50,8 @@ def pass1(state, ast):
|
||||
key = lhs_key(ast.name)
|
||||
assert key not in state.global_identifiers
|
||||
state.global_identifiers.add(key)
|
||||
if ast.path.lexeme.startswith(b"#"):
|
||||
state.colors_lookup[key] = len(state.colors)
|
||||
state.colors.append(ast)
|
||||
else:
|
||||
state.images_lookup[key] = len(state.images)
|
||||
state.images.append(ast)
|
||||
state.images_lookup[key] = len(state.images)
|
||||
state.images.append(ast)
|
||||
elif type(ast) is parse.Define:
|
||||
key = lhs_key(ast.name)
|
||||
assert key not in state.global_identifiers
|
||||
@ -117,43 +107,19 @@ def pass1(state, ast):
|
||||
if type(ast) in simple_statement_types:
|
||||
state.statements.append(ast)
|
||||
|
||||
transforms_set = {
|
||||
b"left",
|
||||
b"centerleft",
|
||||
b"center",
|
||||
b"centerright",
|
||||
b"right",
|
||||
}
|
||||
|
||||
def parse_color(b):
|
||||
assert b.startswith(b"#"), b
|
||||
assert len(b) == 7
|
||||
color = int(b[1:].decode('utf-8'), 16)
|
||||
return color
|
||||
|
||||
def pass2_statement(state, pc, statement):
|
||||
if type(statement) is parse.Play:
|
||||
comment = statement.path.lexeme.decode('utf-8')
|
||||
audio_index = state.audio_lookup[statement.path.lexeme]
|
||||
yield f"{{ .type = type::play, .play = {{ .audioIndex = {audio_index}, /* FIXME channel */ }} }}, // {pc} {comment}"
|
||||
yield f"{{ .type = type::play, .play = {{ .audioIndex = {audio_index} }} }}, // {pc} {comment}"
|
||||
elif type(statement) is parse.Scene:
|
||||
key = lhs_key(statement.name)
|
||||
if key in state.images_lookup:
|
||||
image_index = state.images_lookup[key]
|
||||
comment = ".".join(k.decode('utf-8') for k in key)
|
||||
yield f"{{ .type = type::scene, .scene = {{ .imageIndex = {image_index} }} }}, // {pc} {comment}"
|
||||
else:
|
||||
color_index = state.colors_lookup[key]
|
||||
color = parse_color(state.colors[color_index].path.lexeme)
|
||||
comment = ".".join(k.decode('utf-8') for k in key)
|
||||
yield f"{{ .type = type::scene_color, .scene_color = {{ .color = 0x{color:06x} }} }}, // {pc} {comment}"
|
||||
image_index = state.images_lookup[key]
|
||||
comment = ".".join(k.decode('utf-8') for k in key)
|
||||
yield f"{{ .type = type::scene, .scene = {{ .imageIndex = {image_index} }} }}, // {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)
|
||||
print(f"not implemented: {statement}", file=sys.stderr)
|
||||
pass
|
||||
elif type(statement) is parse.Voice:
|
||||
comment = statement.path.lexeme.decode('utf-8')
|
||||
audio_index = state.audio_lookup[statement.path.lexeme]
|
||||
@ -167,11 +133,8 @@ def pass2_statement(state, pc, statement):
|
||||
elif type(statement) is parse.Show:
|
||||
key = lhs_key(statement.what)
|
||||
image_index = state.images_lookup[key]
|
||||
transform = statement.transform.lexeme
|
||||
assert transform in transforms_set
|
||||
transform = transform.decode('utf-8')
|
||||
comment = ".".join(k.decode('utf-8') for k in key)
|
||||
yield f"{{ .type = type::show, .show = {{ .imageIndex = {image_index}, .transformIndex = transform::{transform} }} }}, // {pc} {comment}"
|
||||
yield f"{{ .type = type::show, .show = {{ .imageIndex = {image_index} }} }}, // {pc} {comment}"
|
||||
elif type(statement) is InternalMenu:
|
||||
count = len(statement.menu.entries)
|
||||
option_index = statement.entry_index
|
||||
@ -189,86 +152,51 @@ def pass2_statement(state, pc, statement):
|
||||
yield f"{{ .type = type::jump, .jump = {{ .statementIndex = {statement_index} }} }}, // {pc} {comment}"
|
||||
elif type(statement) is parse.Return:
|
||||
yield f"{{ .type = type::_return }}, // {pc}"
|
||||
elif type(statement) is parse.Stop:
|
||||
yield f"{{ .type = type::stop, .stop = {{ /* FIXME channel */ }} }}, // {pc}"
|
||||
elif type(statement) is parse.Pause:
|
||||
duration = statement.duration.lexeme
|
||||
yield f"{{ .type = type::pause, .pause = {{ .duration = {duration} }} }}, // {pc}"
|
||||
elif type(statement) is parse.Hide:
|
||||
key = lhs_key(statement.what)
|
||||
image_index = state.images_lookup[key]
|
||||
comment = ".".join(k.decode('utf-8') for k in key)
|
||||
yield f"{{ .type = type::hide, .hide = {{ .imageIndex = {image_index} }} }}, // {pc} {comment}"
|
||||
else:
|
||||
pass
|
||||
assert False, (type(statement), statement)
|
||||
|
||||
def pass2_statements(state):
|
||||
yield "const language::statement statements[] = {"
|
||||
yield "const statement statements[] = {"
|
||||
for pc, statement in enumerate(state.statements):
|
||||
print(pc, statement, file=sys.stderr)
|
||||
yield from pass2_statement(state, pc, statement)
|
||||
yield "};"
|
||||
yield "const int statements_length = (sizeof (statements)) / (sizeof (statements[0]));"
|
||||
|
||||
def pass2_strings(state):
|
||||
yield "char const * const strings[] = {"
|
||||
for string, i in sorted(state.string_lookup.items(), key=lambda kv: kv[1]):
|
||||
yield f"\"{string.decode('utf-8')}\", // {i}"
|
||||
yield "};"
|
||||
yield "const int strings_length = (sizeof (strings)) / (sizeof (strings[0]));"
|
||||
|
||||
def pass2_characters(state):
|
||||
yield "const language::character characters[] = {"
|
||||
yield "const character characters[] = {"
|
||||
for i, character in enumerate(state.characters):
|
||||
character_name, = character.value.args
|
||||
color, = (value.lexeme for key, value in character.value.kwargs if key.lexeme == b'color')
|
||||
color = int(color.decode('utf-8'), 16)
|
||||
yield f"{{ .characterName = \"{character_name.lexeme.decode('utf-8')}\", .color = 0x{color:06x} }}, // {i}"
|
||||
yield f"{{ .characterName = \"{character_name.lexeme.decode('utf-8')}\" }}, // {i}"
|
||||
yield "};"
|
||||
yield "const int characters_length = (sizeof (characters)) / (sizeof (characters[0]));"
|
||||
|
||||
def pass2_audio(state):
|
||||
yield "const language::audio audio[] = {"
|
||||
yield "const audio audio[] = {"
|
||||
for audio, i in sorted(state.audio_lookup.items(), key=lambda kv: kv[1]):
|
||||
orig_path = audio.decode('utf-8')
|
||||
path = orig_path
|
||||
if path.endswith(".mp3"):
|
||||
path = path.removesuffix(".mp3")
|
||||
elif path.endswith(".ogg"):
|
||||
path = path.removesuffix(".ogg")
|
||||
else:
|
||||
assert False, path
|
||||
yield f"{{ .path = \"{path}.opus\" }}, // {i} {orig_path}"
|
||||
yield f"{{ .path = \"{audio.decode('utf-8')}\" }}, // {i}"
|
||||
yield "};"
|
||||
yield "const int audio_length = (sizeof (audio)) / (sizeof (audio[0]));"
|
||||
|
||||
def pass2_images(state):
|
||||
yield "const language::image images[] = {"
|
||||
yield "const image image[] = {"
|
||||
for i, image in enumerate(state.images):
|
||||
orig_path = image.path.lexeme.decode('utf-8')
|
||||
path = orig_path
|
||||
if path.endswith(".png"):
|
||||
path = path.removesuffix(".png")
|
||||
else:
|
||||
assert False, path
|
||||
yield f"{{ .path = \"data/renpy/images/{path}.dds\" }}, // {i} {orig_path}"
|
||||
yield f"{{ .path = \"{image.path.lexeme.decode('utf-8')}\" }}, // {i}"
|
||||
yield "};"
|
||||
yield "const int images_length = (sizeof (images)) / (sizeof (images[0]));"
|
||||
|
||||
def pass2_options(state):
|
||||
yield "const language::option options[] = {"
|
||||
yield "const option options[] = {"
|
||||
for i, (lexeme, statement_index) in sorted(state.entries.items(), key=lambda kv: kv[0]):
|
||||
yield f"{{ .string = \"{lexeme.decode('utf-8')}\", .statementIndex = {statement_index} }}, // {i}"
|
||||
yield "};"
|
||||
yield "const int options_length = (sizeof (options)) / (sizeof (options[0]));"
|
||||
|
||||
def pass2(state):
|
||||
yield "#include \"renpy/language.h\""
|
||||
yield "#include \"renpy/script.h\""
|
||||
yield "#include \"statement.h\""
|
||||
yield ""
|
||||
yield "namespace renpy::script {"
|
||||
yield "using namespace renpy::language;"
|
||||
yield "namespace language {"
|
||||
yield from pass2_strings(state)
|
||||
yield from pass2_characters(state)
|
||||
yield from pass2_audio(state)
|
||||
@ -278,22 +206,17 @@ def pass2(state):
|
||||
yield "}"
|
||||
|
||||
def main():
|
||||
preamble = b"""
|
||||
image _internal_flowers = "flowers.png"
|
||||
"""
|
||||
with open(sys.argv[1], 'rb') as f:
|
||||
mem = memoryview(bytes(chain(preamble, f.read())))
|
||||
mem = memoryview(f.read())
|
||||
|
||||
tokens = list(lex.tokenize(mem))
|
||||
state = State(
|
||||
images = list(),
|
||||
colors = list(),
|
||||
characters = list(),
|
||||
statements = list(),
|
||||
menus = list(),
|
||||
entries = dict(),
|
||||
images_lookup = dict(),
|
||||
colors_lookup = dict(),
|
||||
characters_lookup = dict(),
|
||||
labels_lookup = dict(),
|
||||
audio_lookup = dict(),
|
||||
@ -301,11 +224,9 @@ image _internal_flowers = "flowers.png"
|
||||
global_identifiers = set(),
|
||||
)
|
||||
try:
|
||||
ast_list = []
|
||||
for ast in parse.parse_all(tokens):
|
||||
ast_list.append(ast)
|
||||
ast_list = list(parse.parse_all(tokens))
|
||||
except parse.ParseException as e:
|
||||
print(e, e.token, file=sys.stderr)
|
||||
print(e, e.token)
|
||||
raise
|
||||
|
||||
for t in ast_list:
|
||||
|
||||
@ -23,21 +23,19 @@ struct VSOutput
|
||||
{
|
||||
float4 Position : SV_POSITION;
|
||||
float2 Texture : NORMAL0;
|
||||
float4 Color : Color;
|
||||
};
|
||||
|
||||
[shader("vertex")]
|
||||
VSOutput VSMain(VSInput input)
|
||||
{
|
||||
float2 inverseTexel = float2(1.0 / 128.0, 1.0 / 256.0);
|
||||
float2 inversePixel = float2(1.0 / 1280.0, 1.0 / 720.0);
|
||||
float2 inverseTexel = float2(1.0 / 256.0, 1.0 / 256.0);
|
||||
float2 inversePixel = float2(1.0 / 1024.0, 1.0 / 1024.0);
|
||||
int index = input.InstanceGlyph;
|
||||
|
||||
VSOutput output = (VSOutput)0;
|
||||
float2 position = (input.Texture * Glyphs[index].Size + input.InstancePosition) * inversePixel;
|
||||
output.Position = float4(position * 2.0 - 1.0, 0, 1);
|
||||
output.Texture = (input.Texture * Glyphs[index].Size + Glyphs[index].Position) * inverseTexel;
|
||||
output.Color = input.InstanceColor.zyxw;
|
||||
|
||||
return output;
|
||||
}
|
||||
@ -46,7 +44,5 @@ VSOutput VSMain(VSInput input)
|
||||
float4 PSMain(VSOutput input) : SV_TARGET
|
||||
{
|
||||
float4 color = FontTexture.Sample(ClosestSampler, input.Texture);
|
||||
if (color.x == 0)
|
||||
discard;
|
||||
return float4(input.Color.xyz, color.x);
|
||||
return float4(color.xxx, 1.0);
|
||||
}
|
||||
|
||||
@ -1,95 +0,0 @@
|
||||
[[vk::binding(0, 0)]] SamplerState ClosestSampler;
|
||||
[[vk::binding(1, 0)]] Texture2D Texture[];
|
||||
|
||||
struct VSInput
|
||||
{
|
||||
float2 Position : POSITION0;
|
||||
float2 Texture : TEXCOORD0;
|
||||
// per-instance
|
||||
int2 Size : Size;
|
||||
int2 TopLeft : TopLeft;
|
||||
float4 Color : Color;
|
||||
int TextureIndex : TextureIndex;
|
||||
};
|
||||
|
||||
struct VSOutput
|
||||
{
|
||||
float4 Position : SV_POSITION;
|
||||
float2 Texture : NORMAL0;
|
||||
float4 Color : Color;
|
||||
int TextureIndex : TextureIndex;
|
||||
};
|
||||
|
||||
[shader("vertex")]
|
||||
VSOutput VSMain(VSInput input)
|
||||
{
|
||||
float2 inversePixel = float2(1.0 / 1280.0, 1.0 / 720.0);
|
||||
|
||||
float2 size = abs(input.Size);
|
||||
float2 texture = float2(input.Size.x < 0 ? 1.0 - input.Texture.x : input.Texture.x,
|
||||
input.Size.y < 0 ? 1.0 - input.Texture.y : input.Texture.y);
|
||||
|
||||
VSOutput output = (VSOutput)0;
|
||||
float2 position = (input.Texture * size + input.TopLeft) * inversePixel;
|
||||
output.Position = float4(position * 2.0 - 1.0, 0, 1);
|
||||
output.Texture = texture;
|
||||
output.TextureIndex = input.TextureIndex;
|
||||
output.Color = input.Color.zyxw;
|
||||
|
||||
return output;
|
||||
}
|
||||
|
||||
float4 PSGradient1(VSOutput input) : SV_TARGET
|
||||
{
|
||||
float a = smoothstep(0.05, 0.2, input.Texture.x);
|
||||
float b = 1.0 - smoothstep(0.8, 0.95, input.Texture.x);
|
||||
float c = smoothstep(0.05, 0.2, input.Texture.y);
|
||||
float d = a * b * c * input.Color.w;
|
||||
float3 color = input.Color.xyz;
|
||||
return float4(color, d);
|
||||
}
|
||||
|
||||
float4 PSGradient2(VSOutput input) : SV_TARGET
|
||||
{
|
||||
float a = smoothstep(0.05, 0.2, input.Texture.x);
|
||||
float b = 1.0 - smoothstep(0.8, 0.95, input.Texture.x);
|
||||
float d = a * b * input.Color.w;
|
||||
float3 color = input.Color.xyz;
|
||||
return float4(color, d);
|
||||
}
|
||||
|
||||
float4 PSGradient3(VSOutput input) : SV_TARGET
|
||||
{
|
||||
float a = smoothstep(0.02, 0.1, input.Texture.x);
|
||||
float b = 1.0 - smoothstep(0.9, 0.98, input.Texture.x);
|
||||
float d = a * b * input.Color.w;
|
||||
float3 color = input.Color.xyz;
|
||||
return float4(color, d);
|
||||
}
|
||||
|
||||
[shader("pixel")]
|
||||
float4 PSMain(VSOutput input) : SV_TARGET
|
||||
{
|
||||
float4 color;
|
||||
if (input.TextureIndex >= 0) {
|
||||
color = Texture[input.TextureIndex].Sample(ClosestSampler, input.Texture);
|
||||
} else if (input.TextureIndex == -1) {
|
||||
color = float4(input.Color.xyz, 1.0);
|
||||
} else if (input.TextureIndex == -2) {
|
||||
return PSGradient1(input);
|
||||
} else if (input.TextureIndex == -3) {
|
||||
return PSGradient2(input);
|
||||
} else if (input.TextureIndex == -4) {
|
||||
return PSGradient2(input);
|
||||
} else {
|
||||
return float4(1, 0, 0, 1);
|
||||
}
|
||||
|
||||
if (color.w == 0.0)
|
||||
discard;
|
||||
|
||||
float gamma = 2.2;
|
||||
color.xyz = pow(color.xyz, float3(gamma.xxx));
|
||||
|
||||
return float4(color.xyzw);
|
||||
}
|
||||
@ -1,6 +1,5 @@
|
||||
#include <assert.h>
|
||||
#include <stdint.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#include "new.h"
|
||||
#include "dds/validate.h"
|
||||
@ -72,13 +71,6 @@ static inline dds_size_levels dds_mip_total_size(DXGI_FORMAT dxgiFormat,
|
||||
return {mip_total_size, mip_levels};
|
||||
}
|
||||
|
||||
/*
|
||||
static inline bool is_power_of_two(uint32_t n)
|
||||
{
|
||||
return (n & (n - 1)) == 0;
|
||||
}
|
||||
*/
|
||||
|
||||
namespace dds {
|
||||
DDS_FILE const * validate(void const * data, uint32_t size, uint32_t ** out_offsets, void ** out_data, uint32_t * out_size)
|
||||
{
|
||||
@ -92,21 +84,14 @@ namespace dds {
|
||||
|
||||
uint32_t * offsets = NewM<uint32_t>(dds->header.dwMipMapCount);
|
||||
|
||||
//bool power_of_two = is_power_of_two(dds->header.dwHeight) && is_power_of_two(dds->header.dwWidth);
|
||||
//uint32_t max_mip_levels = power_of_two ? dds->header.dwMipMapCount : 1;
|
||||
uint32_t max_mip_levels = dds->header.dwMipMapCount;
|
||||
|
||||
uintptr_t image_data = ((uintptr_t)dds) + (sizeof (DDS_FILE));
|
||||
dds_size_levels ret = dds_mip_total_size(dds->header10.dxgiFormat,
|
||||
dds->header.dwHeight,
|
||||
dds->header.dwWidth,
|
||||
max_mip_levels,
|
||||
dds->header.dwMipMapCount,
|
||||
offsets);
|
||||
if (ret.size + (sizeof (DDS_FILE)) != size) {
|
||||
fprintf(stderr, "%d %ld %d\n", ret.size, (sizeof (DDS_FILE)), size);
|
||||
}
|
||||
assert(ret.size + (sizeof (DDS_FILE)) == size);
|
||||
assert(ret.levels == max_mip_levels);
|
||||
assert(ret.levels == dds->header.dwMipMapCount);
|
||||
|
||||
*out_offsets = offsets;
|
||||
*out_data = (void *)image_data;
|
||||
|
||||
@ -12,7 +12,6 @@
|
||||
|
||||
#include "font/outline.h"
|
||||
#include "font/outline_types.h"
|
||||
#include "renpy/script.h"
|
||||
|
||||
namespace font::outline {
|
||||
static const _Float16 vertexData[] = {
|
||||
@ -58,7 +57,7 @@ namespace font::outline {
|
||||
load_vertex_index_buffer();
|
||||
load_shader();
|
||||
create_descriptor_sets();
|
||||
loadedFont = load_font(medieval_sharp[0]);
|
||||
loadedFont = load_font(uncial_antiqua[0]);
|
||||
create_glyphs_buffer(loadedFont.font, loadedFont.glyphs);
|
||||
write_descriptor_sets(loadedFont.allocatedImage.imageView);
|
||||
create_instance_buffers();
|
||||
@ -185,14 +184,7 @@ namespace font::outline {
|
||||
};
|
||||
|
||||
VkPipelineColorBlendAttachmentState blendAttachment{
|
||||
.blendEnable = VK_TRUE,
|
||||
.srcColorBlendFactor = VK_BLEND_FACTOR_SRC_ALPHA,
|
||||
.dstColorBlendFactor = VK_BLEND_FACTOR_ONE_MINUS_SRC_ALPHA,
|
||||
.colorBlendOp = VK_BLEND_OP_ADD,
|
||||
.srcAlphaBlendFactor = VK_BLEND_FACTOR_ONE,
|
||||
.dstAlphaBlendFactor = VK_BLEND_FACTOR_ZERO,
|
||||
.alphaBlendOp = VK_BLEND_OP_ADD,
|
||||
.colorWriteMask = 0xF,
|
||||
.colorWriteMask = 0xF
|
||||
};
|
||||
VkPipelineColorBlendStateCreateInfo colorBlendState{
|
||||
.sType = VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO,
|
||||
@ -529,7 +521,7 @@ namespace font::outline {
|
||||
|
||||
VkMemoryRequirements memoryRequirements;
|
||||
vkGetBufferMemoryRequirements(device, instanceBuffer, &memoryRequirements);
|
||||
VkMemoryPropertyFlags memoryPropertyFlags{ VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT };
|
||||
VkMemoryPropertyFlags memoryPropertyFlags{ VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT | VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT };
|
||||
VkMemoryAllocateFlags memoryAllocateFlags{};
|
||||
VkDeviceSize stride;
|
||||
allocateFromMemoryRequirements(device,
|
||||
@ -550,7 +542,7 @@ namespace font::outline {
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
// create glyphs buffer
|
||||
// create instance buffer
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
|
||||
void font::create_glyphs_buffer(types::font const * const font, types::glyph const * const glyphs)
|
||||
@ -611,130 +603,41 @@ namespace font::outline {
|
||||
vkUnmapMemory(device, glyphsMemory);
|
||||
}
|
||||
|
||||
void font::emit_line(int frameIndex,
|
||||
char const * const string,
|
||||
uint32_t x, uint32_t y,
|
||||
int& outputIndex,
|
||||
int startIndex,
|
||||
int endIndex,
|
||||
uint32_t color)
|
||||
{
|
||||
for (int i = startIndex; i < endIndex; i++) {
|
||||
char c = string[i];
|
||||
types::glyph const& glyph = loadedFont.glyphs[c - 32];
|
||||
|
||||
if (c != ' ' && c != '\n') {
|
||||
instanceMappedData[maximumGlyphCount * frameIndex + outputIndex++] = {
|
||||
(uint16_t)((x + glyph.metrics.horiBearingX) >> 6),
|
||||
(uint16_t)((y - glyph.metrics.horiBearingY) >> 6),
|
||||
(uint32_t)(c - 32),
|
||||
color,
|
||||
};
|
||||
}
|
||||
|
||||
x += glyph.metrics.horiAdvance;
|
||||
}
|
||||
}
|
||||
|
||||
void font::centered(int frameIndex, char const * const string, uint32_t& x, uint32_t& y,
|
||||
uint32_t minX,
|
||||
uint32_t maxWidth,
|
||||
int& outputIndex,
|
||||
uint32_t color)
|
||||
{
|
||||
int stringIndex = 0;
|
||||
int lineStart = stringIndex;
|
||||
int lineWidth = 0;
|
||||
uint32_t leftOffset = 0;
|
||||
|
||||
while (true) {
|
||||
char c = string[stringIndex++];
|
||||
if (c == 0)
|
||||
break;
|
||||
|
||||
if (c == '\n') {
|
||||
continue;
|
||||
}
|
||||
|
||||
types::glyph const& glyph = loadedFont.glyphs[c - 32];
|
||||
|
||||
if (lineWidth == 0) {
|
||||
leftOffset = glyph.metrics.horiBearingX;
|
||||
}
|
||||
|
||||
lineWidth += glyph.metrics.horiAdvance;
|
||||
|
||||
if ((lineWidth - leftOffset) + loadedFont.font->face_metrics.max_advance > (maxWidth << 6)) {
|
||||
while (string[stringIndex] != ' ') {
|
||||
char c = string[--stringIndex];
|
||||
types::glyph const& glyph = loadedFont.glyphs[c - 32];
|
||||
lineWidth -= glyph.metrics.horiAdvance;
|
||||
}
|
||||
uint32_t center = (minX + (maxWidth / 2)) << 6;
|
||||
uint32_t left = center - (lineWidth / 2);
|
||||
emit_line(frameIndex, string, left - leftOffset, y, outputIndex, lineStart, stringIndex, color);
|
||||
while (string[stringIndex] == ' ') stringIndex++;
|
||||
lineStart = stringIndex;
|
||||
lineWidth = 0;
|
||||
y += loadedFont.font->face_metrics.height * 1.2;
|
||||
x = minX << 6;
|
||||
}
|
||||
};
|
||||
if (stringIndex != lineStart) {
|
||||
uint32_t center = (minX + (maxWidth / 2)) << 6;
|
||||
uint32_t left = center - (lineWidth / 2);
|
||||
emit_line(frameIndex, string, left - leftOffset, y, outputIndex, lineStart, stringIndex, color);
|
||||
y += loadedFont.font->face_metrics.height * 1.2;
|
||||
x = minX << 6;
|
||||
}
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
// draw
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
|
||||
void font::draw(VkCommandBuffer commandBuffer,
|
||||
uint32_t frameIndex,
|
||||
renpy::interpreter const& state)
|
||||
uint32_t frameIndex)
|
||||
{
|
||||
// transfer
|
||||
const char * string = "so when Nico wants to run this game on his\n4K monitor, he gets a dinky little 1280x720\nwindow instead?";
|
||||
int outputIndex = 0;
|
||||
int stringIndex = 0;
|
||||
|
||||
if (state.menu.count == 0) {
|
||||
if (state.say.stringIndex != -1u) {
|
||||
char const * const string = renpy::script::strings[state.say.stringIndex];
|
||||
uint32_t x = textboxLeft << 6;
|
||||
uint32_t y = 590 << 6;
|
||||
centered(frameIndex, string,
|
||||
x, y,
|
||||
textboxLeft, textboxWidth,
|
||||
outputIndex,
|
||||
0x000000);
|
||||
uint32_t x = 64 << 6;
|
||||
uint32_t y = 64 << 6;
|
||||
while (true) {
|
||||
char c = string[stringIndex++];
|
||||
if (c == 0)
|
||||
break;
|
||||
|
||||
if (c != ' ') {
|
||||
instanceMappedData[maximumGlyphCount * frameIndex + outputIndex++] = {
|
||||
(uint16_t)((x + loadedFont.glyphs[c - 32].metrics.horiBearingX) >> 6),
|
||||
(uint16_t)((y - loadedFont.glyphs[c - 32].metrics.horiBearingY) >> 6),
|
||||
(uint32_t)(c - 32),
|
||||
0xaabbccdd,
|
||||
};
|
||||
}
|
||||
|
||||
if (state.say.characterIndex != -1u) {
|
||||
const renpy::language::character & character = renpy::script::characters[state.say.characterIndex];
|
||||
char const * const string = character.characterName;
|
||||
uint32_t x = 580 << 6;
|
||||
uint32_t y = 550 << 6;
|
||||
centered(frameIndex, string,
|
||||
x, y,
|
||||
580, 118,
|
||||
outputIndex,
|
||||
character.color);
|
||||
if (c == '\n') {
|
||||
y += loadedFont.font->face_metrics.height * 1.2;
|
||||
x = 64 << 6;
|
||||
} else {
|
||||
x += loadedFont.glyphs[c - 32].metrics.horiAdvance;
|
||||
}
|
||||
} else {
|
||||
for (uint32_t i = 0; i < state.menu.count; i++) {
|
||||
uint32_t x = 400 << 6;
|
||||
uint32_t y = (100 * i + 130) << 6;
|
||||
centered(frameIndex, renpy::script::options[state.menu.optionIndex + i].string,
|
||||
x, y,
|
||||
400, 480,
|
||||
outputIndex,
|
||||
0x000000);
|
||||
}
|
||||
}
|
||||
|
||||
};
|
||||
// flush
|
||||
constexpr int mappedMemoryRangesCount = 1;
|
||||
VkMappedMemoryRange mappedMemoryRanges[mappedMemoryRangesCount]{
|
||||
@ -742,7 +645,7 @@ namespace font::outline {
|
||||
.sType = VK_STRUCTURE_TYPE_MAPPED_MEMORY_RANGE,
|
||||
.memory = instanceMemory,
|
||||
.offset = 0,
|
||||
.size = (sizeof (GlyphInstance)) * outputIndex,
|
||||
.size = (sizeof (GlyphInstance)),
|
||||
}
|
||||
};
|
||||
alignMappedMemoryRanges(physicalDeviceProperties.limits.nonCoherentAtomSize,
|
||||
|
||||
86
src/main.cpp
@ -21,9 +21,6 @@
|
||||
|
||||
#include "minecraft/vulkan.h"
|
||||
#include "font/outline.h"
|
||||
#include "renpy/vulkan.h"
|
||||
#include "renpy/interpreter.h"
|
||||
#include "renpy/interact.h"
|
||||
|
||||
#include "scenes/shadow_test/shadow_test.h"
|
||||
#include "scenes/eidelwind/eidelwind.h"
|
||||
@ -499,7 +496,7 @@ int main()
|
||||
// window and surface
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
|
||||
SDL_Window * window = SDL_CreateWindow("Vulkan", 1280, 720, SDL_WINDOW_VULKAN | SDL_WINDOW_RESIZABLE);
|
||||
SDL_Window * window = SDL_CreateWindow("Vulkan", 1024, 1024, SDL_WINDOW_VULKAN | SDL_WINDOW_RESIZABLE);
|
||||
SDL_CHECK_NONNULL(window);
|
||||
SDL_CHECK(SDL_Vulkan_CreateSurface(window, instance, nullptr, &surface));
|
||||
SDL_CHECK(SDL_GetWindowSize(window, &windowSize.x, &windowSize.y));
|
||||
@ -549,8 +546,8 @@ int main()
|
||||
|
||||
createDepth(physicalDeviceProperties.limits.nonCoherentAtomSize,
|
||||
physicalDeviceMemoryProperties,
|
||||
1280,
|
||||
720,
|
||||
1024,
|
||||
1024,
|
||||
depthFormat,
|
||||
VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT | VK_IMAGE_USAGE_SAMPLED_BIT,
|
||||
shadowArrayLayers,
|
||||
@ -649,7 +646,6 @@ int main()
|
||||
// initialize collada
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
|
||||
/*
|
||||
collada::scene::state collada_state;
|
||||
|
||||
collada_state.vulkan.initial_state(instance,
|
||||
@ -665,13 +661,11 @@ int main()
|
||||
|
||||
collada::types::descriptor const * collada_scene_descriptor = &eidelwind::descriptor;
|
||||
collada_state.load_scene(collada_scene_descriptor);
|
||||
*/
|
||||
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
// initialize minecraft
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
|
||||
/*
|
||||
minecraft::vulkan::vulkan minecraft_state;
|
||||
minecraft_state.initial_state(instance,
|
||||
device,
|
||||
@ -684,7 +678,6 @@ int main()
|
||||
textureSamplers[2],
|
||||
shadowDepthImageViewDepth);
|
||||
minecraft_state.init();
|
||||
*/
|
||||
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
// initialize font
|
||||
@ -702,34 +695,10 @@ int main()
|
||||
textureSamplers[2]);
|
||||
font_state.init();
|
||||
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
// initialize renpy
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
|
||||
renpy::vulkan renpy_state;
|
||||
renpy_state.initial_state(instance,
|
||||
device,
|
||||
queue,
|
||||
commandPool,
|
||||
physicalDeviceProperties,
|
||||
physicalDeviceMemoryProperties,
|
||||
surfaceFormat.format,
|
||||
depthFormat,
|
||||
textureSamplers[2]);
|
||||
renpy_state.init();
|
||||
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
// interpreter
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
|
||||
renpy::interpreter interpreter_state;
|
||||
interpreter_state.reset();
|
||||
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
// initialize view
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
|
||||
/*
|
||||
int cameraIndex = collada_state.find_node_index_by_name("Camera001");
|
||||
int cameraTargetIndex = collada_state.find_node_index_by_name("EidelwindRigPelvis");
|
||||
int lightIndex = collada_state.find_node_index_by_name("Camera001");
|
||||
@ -750,7 +719,6 @@ int main()
|
||||
viewState.forward = XMVectorSetZ(XMVector3Normalize(at - eye), 0);
|
||||
viewState.pitch = 0;
|
||||
viewState.applyTransform(0, 0, 0, 0, 0);
|
||||
*/
|
||||
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
// loop
|
||||
@ -764,11 +732,9 @@ int main()
|
||||
int64_t start_time;
|
||||
SDL_GetCurrentTime(&start_time);
|
||||
|
||||
//collada_state.update(0);
|
||||
collada_state.update(0);
|
||||
|
||||
while (quit == false) {
|
||||
interpreter_state.interpret();
|
||||
|
||||
SDL_Event event;
|
||||
while (SDL_PollEvent(&event)) {
|
||||
if (event.type == SDL_EVENT_QUIT) {
|
||||
@ -795,10 +761,10 @@ int main()
|
||||
}
|
||||
if (event.type == SDL_EVENT_MOUSE_MOTION) {
|
||||
if (event.motion.state & SDL_BUTTON_LMASK) {
|
||||
//collada_state.mouse_motion(cameraIndex, cameraTargetIndex, event.motion.xrel, event.motion.yrel, 0);
|
||||
collada_state.mouse_motion(cameraIndex, cameraTargetIndex, event.motion.xrel, event.motion.yrel, 0);
|
||||
}
|
||||
if (event.motion.state & SDL_BUTTON_RMASK) {
|
||||
//collada_state.mouse_motion(cameraIndex, cameraTargetIndex, event.motion.xrel, event.motion.yrel, 1);
|
||||
collada_state.mouse_motion(cameraIndex, cameraTargetIndex, event.motion.xrel, event.motion.yrel, 1);
|
||||
}
|
||||
}
|
||||
if (event.type == SDL_EVENT_WINDOW_RESIZED) {
|
||||
@ -816,14 +782,14 @@ int main()
|
||||
// gamepad update
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
|
||||
//gamepad_update(viewState);
|
||||
gamepad_update(viewState);
|
||||
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
// collada update
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
|
||||
//double time = getTime(start_time);
|
||||
//collada_state.update(time / 1.5f);
|
||||
double time = getTime(start_time);
|
||||
collada_state.update(time / 1.5f);
|
||||
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
// fence
|
||||
@ -850,7 +816,6 @@ int main()
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
|
||||
if (0) {
|
||||
/*
|
||||
collada_state.vulkan.change_frame(commandBuffer, frameIndex);
|
||||
|
||||
XMMATRIX projection = currentProjection();
|
||||
@ -871,16 +836,13 @@ int main()
|
||||
lightPositionWorld,
|
||||
collada_state.descriptor->nodes_count,
|
||||
collada_state.node_state.node_instances);
|
||||
*/
|
||||
|
||||
// minecraft
|
||||
|
||||
/*
|
||||
minecraft_state.transfer_transforms(projection,
|
||||
view,
|
||||
lightPositionWorld,
|
||||
frameIndex);
|
||||
*/
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
@ -925,7 +887,7 @@ int main()
|
||||
|
||||
VkRenderingInfo shadowRenderingInfo{
|
||||
.sType = VK_STRUCTURE_TYPE_RENDERING_INFO,
|
||||
.renderArea{ .extent{ .width = 1280, .height = 720 } },
|
||||
.renderArea{ .extent{ .width = 1024, .height = 1024 } },
|
||||
.layerCount = 6,
|
||||
.colorAttachmentCount = 0,
|
||||
.pDepthAttachment = &shadowDepthRenderingAttachmentInfo,
|
||||
@ -938,24 +900,24 @@ int main()
|
||||
VkViewport shadowViewport{
|
||||
.x = 0,
|
||||
.y = 0,
|
||||
.width = 1280,
|
||||
.height = 720,
|
||||
.width = 1024,
|
||||
.height = 1024,
|
||||
.minDepth = 0.0f,
|
||||
.maxDepth = 1.0f
|
||||
};
|
||||
vkCmdSetViewport(commandBuffer, 0, 1, &shadowViewport);
|
||||
VkRect2D shadowScissor{
|
||||
.extent{
|
||||
.width = 1280,
|
||||
.height = 720
|
||||
.width = 1024,
|
||||
.height = 1024
|
||||
}
|
||||
};
|
||||
vkCmdSetScissor(commandBuffer, 0, 1, &shadowScissor);
|
||||
|
||||
// draw
|
||||
|
||||
//collada_state.vulkan.excludeMaterialIndex = lightMaterialIndex;
|
||||
//collada_state.vulkan.pipelineIndex = 0; // shadow pipeline
|
||||
collada_state.vulkan.excludeMaterialIndex = lightMaterialIndex;
|
||||
collada_state.vulkan.pipelineIndex = 0; // shadow pipeline
|
||||
//collada_state.draw();
|
||||
|
||||
vkCmdEndRendering(commandBuffer);
|
||||
@ -1076,21 +1038,15 @@ int main()
|
||||
|
||||
// draw
|
||||
|
||||
//collada_state.vulkan.excludeMaterialIndex = -1;
|
||||
//collada_state.vulkan.pipelineIndex = 1; // non-shadow pipeline
|
||||
collada_state.vulkan.excludeMaterialIndex = -1;
|
||||
collada_state.vulkan.pipelineIndex = 1; // non-shadow pipeline
|
||||
//collada_state.draw();
|
||||
//collada_state.vulkan.pipelineIndex = 2; // geometry shader pipeline
|
||||
//collada_state.draw();
|
||||
|
||||
//minecraft_state.draw(commandBuffer, frameIndex);
|
||||
|
||||
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);
|
||||
renpy_state.draw(commandBuffer, frameIndex, interpreter_state, mx, my);
|
||||
font_state.draw(commandBuffer, frameIndex, interpreter_state);
|
||||
font_state.draw(commandBuffer, frameIndex);
|
||||
|
||||
vkCmdEndRendering(commandBuffer);
|
||||
|
||||
@ -1182,8 +1138,8 @@ int main()
|
||||
|
||||
VK_CHECK(vkDeviceWaitIdle(device));
|
||||
|
||||
//collada_state.vulkan.destroy_all(collada_scene_descriptor);
|
||||
//collada_state.unload_scene();
|
||||
collada_state.vulkan.destroy_all(collada_scene_descriptor);
|
||||
collada_state.unload_scene();
|
||||
|
||||
for (uint32_t i = 0; i < maxFramesInFlight; i++) {
|
||||
vkDestroyFence(device, fences[i], nullptr);
|
||||
|
||||
@ -1,47 +0,0 @@
|
||||
#include <assert.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#include "renpy/script.h"
|
||||
#include "renpy/interact.h"
|
||||
|
||||
namespace renpy {
|
||||
bool overlap(int width, int height, int x, int y, int mx, int my)
|
||||
{
|
||||
int minX = x;
|
||||
int minY = y;
|
||||
int maxX = x + width;
|
||||
int maxY = y + height;
|
||||
|
||||
return mx >= minX && mx <= maxX && my >= minY && my <= maxY;
|
||||
}
|
||||
|
||||
static bool lastmLeft = false;
|
||||
|
||||
void update(interpreter & state, int mx, int my, bool mLeft)
|
||||
{
|
||||
bool mDown = mLeft && (!lastmLeft);
|
||||
lastmLeft = mLeft;
|
||||
if (mDown) {
|
||||
state.interactionWait = false;
|
||||
}
|
||||
|
||||
if (state.menu.count == 0 || !mDown)
|
||||
return;
|
||||
|
||||
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);
|
||||
if (overlap) {
|
||||
// jump to menu item
|
||||
uint32_t optionIndex = state.menu.optionIndex + i;
|
||||
assert(optionIndex < (uint32_t)script::options_length);
|
||||
uint32_t next_pc = script::options[optionIndex].statementIndex;
|
||||
fprintf(stderr, "interact[%d]: menu jump %d\n", state.pc, next_pc);
|
||||
state.pc = next_pc;
|
||||
state.menu.count = 0;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1,138 +0,0 @@
|
||||
#include <assert.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#include "renpy/script.h"
|
||||
#include "renpy/interpreter.h"
|
||||
|
||||
namespace renpy {
|
||||
void interpreter::reset()
|
||||
{
|
||||
pc = 0;
|
||||
backgroundIndex = -1;
|
||||
backgroundColor = 0;
|
||||
shownImagesCount = 0;
|
||||
say.stringIndex = -1;
|
||||
say.characterIndex = -1;
|
||||
menu.count = 0;
|
||||
interactionWait = false;
|
||||
}
|
||||
|
||||
uint32_t interpreter::findImage(uint32_t imageIndex)
|
||||
{
|
||||
for (uint32_t i = 0; i < shownImagesCount; i++) {
|
||||
if (shownImages[i].imageIndex == imageIndex) {
|
||||
return i;
|
||||
}
|
||||
}
|
||||
return ~0u;
|
||||
}
|
||||
|
||||
void interpreter::showImage(uint32_t imageIndex, uint32_t transformIndex)
|
||||
{
|
||||
uint32_t shownImageIndex = findImage(imageIndex);
|
||||
if (shownImageIndex == ~0u) {
|
||||
shownImageIndex = shownImagesCount;
|
||||
shownImagesCount += 1;
|
||||
}
|
||||
|
||||
shownImages[shownImageIndex].imageIndex = imageIndex;
|
||||
shownImages[shownImageIndex].transformIndex = transformIndex;
|
||||
|
||||
assert(shownImagesCount <= maximumShownImagesCount);
|
||||
printf("shownImagesCount: %d\n", shownImagesCount);
|
||||
}
|
||||
|
||||
void interpreter::hideImage(uint32_t imageIndex)
|
||||
{
|
||||
uint32_t shownImageIndex = findImage(imageIndex);
|
||||
if (shownImageIndex == ~0u)
|
||||
return;
|
||||
|
||||
for (uint32_t i = shownImageIndex; i < (shownImagesCount - 1); i++) {
|
||||
shownImages[i] = shownImages[i+1];
|
||||
printf("here\n");
|
||||
}
|
||||
printf("return\n");
|
||||
shownImagesCount -= 1;
|
||||
}
|
||||
|
||||
void interpreter::interpret_one()
|
||||
{
|
||||
assert(pc < (uint32_t)script::statements_length);
|
||||
|
||||
language::statement const& statement = script::statements[pc];
|
||||
|
||||
switch (statement.type) {
|
||||
case language::type::play:
|
||||
fprintf(stderr, "interpret_one[%d]: play\n", pc);
|
||||
pc += 1;
|
||||
break;
|
||||
case language::type::scene_color:
|
||||
fprintf(stderr, "interpret_one[%d]: scene_color\n", pc);
|
||||
backgroundIndex = -1;
|
||||
backgroundColor = statement.scene_color.color;
|
||||
pc += 1;
|
||||
break;
|
||||
case language::type::scene:
|
||||
fprintf(stderr, "interpret_one[%d]: scene\n", pc);
|
||||
assert(statement.scene.imageIndex < (uint32_t)script::images_length);
|
||||
backgroundIndex = statement.scene.imageIndex;
|
||||
shownImagesCount = 0;
|
||||
say.stringIndex = -1;
|
||||
say.characterIndex = -1;
|
||||
pc += 1;
|
||||
break;
|
||||
case language::type::say:
|
||||
fprintf(stderr, "interpret_one[%d]: say\n", pc);
|
||||
assert(statement.say.stringIndex < (uint32_t)script::strings_length);
|
||||
say.stringIndex = statement.say.stringIndex;
|
||||
say.characterIndex = statement.say.characterIndex;
|
||||
interactionWait = true;
|
||||
pc += 1;
|
||||
break;
|
||||
case language::type::hide:
|
||||
fprintf(stderr, "interpret_one[%d]: hide\n", pc);
|
||||
assert(statement.show.imageIndex < (uint32_t)script::images_length);
|
||||
assert(statement.show.transformIndex < transformsCount);
|
||||
hideImage(statement.show.imageIndex);
|
||||
pc += 1;
|
||||
break;
|
||||
case language::type::show:
|
||||
fprintf(stderr, "interpret_one[%d]: show\n", pc);
|
||||
assert(statement.show.imageIndex < (uint32_t)script::images_length);
|
||||
assert(statement.show.transformIndex < transformsCount);
|
||||
showImage(statement.show.imageIndex, statement.show.transformIndex);
|
||||
pc += 1;
|
||||
break;
|
||||
case language::type::menu:
|
||||
fprintf(stderr, "interpret_one[%d]: menu\n", pc);
|
||||
assert(statement.menu.optionIndex < (uint32_t)script::options_length);
|
||||
assert(statement.menu.count > 0);
|
||||
menu.count = statement.menu.count;
|
||||
menu.optionIndex = statement.menu.optionIndex;
|
||||
pc += 1;
|
||||
break;
|
||||
case language::type::jump:
|
||||
fprintf(stderr, "interpret_one[%d]: jump %d\n", pc, statement.jump.statementIndex);
|
||||
assert(statement.jump.statementIndex < (uint32_t)script::statements_length);
|
||||
pc = statement.jump.statementIndex;
|
||||
break;
|
||||
default:
|
||||
fprintf(stderr, "unknown statement type at pc %d\n", pc);
|
||||
pc += 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void interpreter::interpret()
|
||||
{
|
||||
while (!interactionWait) {
|
||||
//while (true) {
|
||||
uint32_t last_pc = pc;
|
||||
interpret_one();
|
||||
assert(pc != last_pc);
|
||||
|
||||
//if (pc == 18) break;
|
||||
}
|
||||
}
|
||||
};
|
||||
@ -1,488 +0,0 @@
|
||||
#include "renpy/language.h"
|
||||
#include "renpy/script.h"
|
||||
|
||||
namespace renpy::script {
|
||||
using namespace renpy::language;
|
||||
|
||||
char const * const strings[] = {
|
||||
"Far over the mountains of Almystice", // 0
|
||||
"Beyond the tumultuous waters of the Lilac Bay", // 1
|
||||
"And across the vast fields of Alysen", // 2
|
||||
"Tiny minstrels can be heard amongst the trees", // 3
|
||||
"Are we almost there?", // 4
|
||||
"Hmmm... Not really", // 5
|
||||
"How much further have we to go?", // 6
|
||||
"About two more moons", // 7
|
||||
"We are still sooo far awayyy", // 8
|
||||
"And it will be even further if you dont stop complaining", // 9
|
||||
"Easy for you to say, all you have to carry is a little memory pipe!", // 10
|
||||
"I'm tired ><", // 11
|
||||
"Don't start whining now!", // 12
|
||||
"You need to remember why we have come all this way", // 13
|
||||
"I understand... I suppose it is for an important purpose", // 14
|
||||
"We're almost out of the forest, we can take a little break once we clear the tree line", // 15
|
||||
"Is that where the flora field is?", // 16
|
||||
"Why yes, If I remember correctly, it should be just up ahead", // 17
|
||||
"As the minstrel mice girls continue along the path, the forest opens up into a beautiful field of flowers", // 18
|
||||
"Look at all the butterflies! They are all so pretty!", // 19
|
||||
"This place is like a dream...", // 20
|
||||
"There are so many flowers this time of year", // 21
|
||||
"I told you it would be worth the journey!", // 22
|
||||
"Can we stop for a bit now?", // 23
|
||||
"Of course", // 24
|
||||
"Ya know, Its a shame we didnt save some of those giant strawberries you found", // 25
|
||||
"I told you not to eat them all!", // 26
|
||||
"Yah yah", // 27
|
||||
"Anyways, shall I recite a tale?", // 28
|
||||
"Why dont you sing the story of Eleanor the Hero!", // 29
|
||||
"Sure", // 30
|
||||
"...", // 31
|
||||
"Serves you right for scaring those elephant-dogs", // 32
|
||||
"They were asking for it, you know", // 33
|
||||
"Rawrrrr", // 34
|
||||
"AHHHHHHHHHH!!!!!", // 35
|
||||
"Nyanyanyanya", // 36
|
||||
"Well, what do we have here? If it isn't two little meowse girls, all alone amongst the flowers", // 37
|
||||
"Please don't eat us!!!", // 38
|
||||
"Alice don't run, our only chance is through pleading!", // 39
|
||||
"Please don't eat us, miss kitty cat!!! ><", // 40
|
||||
"I'm not gonna eat you nyanyanya", // 41
|
||||
"I just want to know what two little meowses are doing so very far away from home", // 42
|
||||
"Also, are you minstrels?", // 43
|
||||
"Y-Yes", // 44
|
||||
"W-We are on a quest to Castle Alysen...", // 45
|
||||
"Shh don't tell her that", // 46
|
||||
"The Castle of Alysen you say?!?", // 47
|
||||
"Why, that's where I am headed!", // 48
|
||||
"You don't say...", // 49
|
||||
"Yah, I do actually", // 50
|
||||
"So... Why might you be traveling to the castle?", // 51
|
||||
"I belong to the lineage of Agrepen", // 52
|
||||
"And what might that mean?", // 53
|
||||
"The Agrepens are a long line of felines loyal to the crown of corvidae", // 54
|
||||
"Really? That must mean you are a noble?", // 55
|
||||
"Well, not really...", // 56
|
||||
"My father was one of the queens knights many years ago", // 57
|
||||
"Ah I see", // 58
|
||||
"So do you live at the castle or something?", // 59
|
||||
"Well, no...", // 60
|
||||
"Then why are you traveling to Castle Alysen?", // 61
|
||||
"uhhh", // 62
|
||||
"I DONT NEED TO BE PRESSURED BY LITTLE MICE TO SAY ANYTHING!!!!", // 63
|
||||
"GOOD DAY!", // 64
|
||||
"Wha...", // 65
|
||||
"Phew, I was scared she was gonna follow us the whole way", // 66
|
||||
"She didn't seem so bad", // 67
|
||||
"Are you kidding? She's a crazy kitty!", // 68
|
||||
"After their encounter with the weird cat, the mice scurry out of the flower field and into the nearby meadow", // 69
|
||||
"I think this is the right way...", // 70
|
||||
"Then where did the path go?", // 71
|
||||
"How am I supposed to know?", // 72
|
||||
"Did you hear that?!?!", // 73
|
||||
"Hey there...", // 74
|
||||
"I apologize", // 75
|
||||
"I didn't mean to storm off like that", // 76
|
||||
"Ha ha, no problem...", // 77
|
||||
"So... Why are you traveling to Castle Alysen?", // 78
|
||||
"Alice!!!", // 79
|
||||
"If you must know, I have been summoned by the queen", // 80
|
||||
"I suspect that my poor reputation amongst the locals of Eastern Nidus has come back to haunt me", // 81
|
||||
"Though I know not what what she has summoned me for", // 82
|
||||
"Ahhhhhh", // 83
|
||||
"So then...", // 84
|
||||
"Why are YOU traveling to the Castle?", // 85
|
||||
"We are delivering a feather!!!", // 86
|
||||
"Alice no!", // 87
|
||||
"A feather that belonged to the queen herself!!!", // 88
|
||||
"Why you little...", // 89
|
||||
"A feather you say? One of the queens?", // 90
|
||||
"How on the face of Al Mot might you have aquired such a thing?", // 91
|
||||
"If it is authentic, that is...", // 92
|
||||
"Since Alice cannot keep a secret, I shall tell you", // 93
|
||||
"Seven moons ago, our town was attacked by three owls and a band of mice from the northern principalities", // 94
|
||||
"Eventually word spread to greater nearby settlements, and so", // 95
|
||||
"Messengers from the keep in Musia sent for aid from the Ravens", // 96
|
||||
"Four moons ago, the request was answered", // 97
|
||||
"And a small group of mice accompanied by two ravens a fox, and three squirrels set out to the northern principalities", // 98
|
||||
"Anyways, long story short, we drove those barbaric rats out of their home", // 99
|
||||
"They arent actual rats you know", // 100
|
||||
"Obviously, but you wont catch me speaking kindly of them", // 101
|
||||
"And you forgot the most important part", // 102
|
||||
"Yah yah, I am getting there", // 103
|
||||
"So, essentially, my brother is trained in archery, and...", // 104
|
||||
"Speed it up already", // 105
|
||||
"You tell it then!", // 106
|
||||
"My cousin found this feather in one of the highest towers of a castle far to the north", // 107
|
||||
"How do you know it belongs to the queen?", // 108
|
||||
"It said so itself above the display on the wall", // 109
|
||||
"Supposedly, it was in a room filled with treasures!", // 110
|
||||
"That is very nice and all, but what are the two of you doing out here all alone?", // 111
|
||||
"Do you expect every bird in Avia to respect your alliance with Castle Alysen?", // 112
|
||||
"What do you mean?", // 113
|
||||
"I mean, the two of you probably look like walking dinner to most creatures", // 114
|
||||
"I could go for some dinner...", // 115
|
||||
"Anyways...", // 116
|
||||
"To answer your question, upon returning to the village, the feather was taken from my brother by the needle guild", // 117
|
||||
"So... Yesterday, after sundown", // 118
|
||||
"We stole the feather from the guild hall before vanishing into the night", // 119
|
||||
"Can you imagine the look on their stupid faces, when they woke up, and not only is the feather missing", // 120
|
||||
"But so are we!", // 121
|
||||
"Hahahaha", // 122
|
||||
"Are the two of you mad?", // 123
|
||||
"I assume you are attempting to return the Queens feather?", // 124
|
||||
"Yes, we intend to deliver the feather to its rightful owner", // 125
|
||||
"Absolute madness!", // 126
|
||||
"I will follow the two of you", // 127
|
||||
"To keep you safe, that is", // 128
|
||||
"Alright!", // 129
|
||||
"Ha ha... Okay...", // 130
|
||||
"Great! Follow me, I know a shortcut! :3", // 131
|
||||
"Sounds good!", // 132
|
||||
"Oh dear!", // 133
|
||||
"And so the mice girls follow the noble cat further towards their destination", // 134
|
||||
"Nya", // 135
|
||||
"Look, your right, the castle is just up ahead!", // 136
|
||||
"Wait up", // 137
|
||||
"I told you I knew a shortcut!", // 138
|
||||
"Most people take the long way around", // 139
|
||||
"Yah because these are royal wheatfields!", // 140
|
||||
"Who cares?", // 141
|
||||
"Are you trying to get us killed?", // 142
|
||||
"Its trespassing on royal land!", // 143
|
||||
"Calm down, I have done this a million times", // 144
|
||||
"That doesnt make me calm!", // 145
|
||||
"How can the rolling fields of wheat not calm your spirit?", // 146
|
||||
"You little mice truly are mad!", // 147
|
||||
"I like the wheat!", // 148
|
||||
"Shut up!", // 149
|
||||
"Sounds like someone needs a nap!", // 150
|
||||
"Why? because I'm not insane like you?", // 151
|
||||
"Yah, your so sane, that you decided to steal from your town and then run off alone to the country of birds", // 152
|
||||
"The power of friendship wont protect the two of you from becoming dinner", // 153
|
||||
"And that, is why I feel obligated to accompany you!", // 154
|
||||
"Hey, we have a good reason!", // 155
|
||||
"And what might that be?", // 156
|
||||
"My brother found the feather, not the town guild, its a matter of family pride!", // 157
|
||||
"Pride has touched the chosen meouse", // 158
|
||||
"Flies she towards the Castle", // 159
|
||||
"But her ambition burns far too bright, and silly myice dont have any wings to myelt", // 160
|
||||
"What?", // 161
|
||||
"Nyanyanya", // 162
|
||||
"Nyevermind", // 163
|
||||
"Sing me a song little minstrels!", // 164
|
||||
"Very Nyice!", // 165
|
||||
"Now tell me little minstrels, what are your names?", // 166
|
||||
"My name is Alice", // 167
|
||||
"And my name is Eily", // 168
|
||||
"What is your name?", // 169
|
||||
"My name is Leona!", // 170
|
||||
"And so, the odd trio walked through the wheatfields and towards the castle walls", // 171
|
||||
"Upon approaching the castle walls", // 172
|
||||
};
|
||||
|
||||
const int strings_length = (sizeof (strings)) / (sizeof (strings[0]));
|
||||
|
||||
const language::character characters[] = {
|
||||
{ .characterName = "Alice", .color = 0x00765e }, // 0
|
||||
{ .characterName = "Cat", .color = 0x590093 }, // 1
|
||||
{ .characterName = "Eily", .color = 0x0b6092 }, // 2
|
||||
{ .characterName = "Mouse Girls", .color = 0x000000 }, // 3
|
||||
{ .characterName = "Narrator", .color = 0x000000 }, // 4
|
||||
{ .characterName = "Leona", .color = 0x590093 }, // 5
|
||||
};
|
||||
|
||||
const int characters_length = (sizeof (characters)) / (sizeof (characters[0]));
|
||||
|
||||
const language::audio audio[] = {
|
||||
{ .path = "sfx/Chime.opus" }, // 0 sfx/Chime.ogg
|
||||
{ .path = "sfx/MistAmbience.opus" }, // 1 sfx/MistAmbience.ogg
|
||||
{ .path = "music/TinyForestMinstrels.opus" }, // 2 music/TinyForestMinstrels.ogg
|
||||
{ .path = "n5test.opus" }, // 3 n5test.ogg
|
||||
{ .path = "music/PhrygianButterflies.opus" }, // 4 music/PhrygianButterflies.ogg
|
||||
{ .path = "music/Poem1.opus" }, // 5 music/Poem1.ogg
|
||||
{ .path = "placeholdermeow.opus" }, // 6 placeholdermeow.mp3
|
||||
{ .path = "music/ScaredMice.opus" }, // 7 music/ScaredMice.ogg
|
||||
{ .path = "music/WheatFields.opus" }, // 8 music/WheatFields.ogg
|
||||
};
|
||||
|
||||
const int audio_length = (sizeof (audio)) / (sizeof (audio[0]));
|
||||
|
||||
const language::image images[] = {
|
||||
{ .path = "data/renpy/images/flowers.dds" }, // 0 flowers.png
|
||||
{ .path = "data/renpy/images/bg/forest1.dds" }, // 1 bg/forest1.png
|
||||
{ .path = "data/renpy/images/bg/forest2.dds" }, // 2 bg/forest2.png
|
||||
{ .path = "data/renpy/images/bg/flowerfield1.dds" }, // 3 bg/flowerfield1.png
|
||||
{ .path = "data/renpy/images/bg/wheatfield1.dds" }, // 4 bg/wheatfield1.png
|
||||
{ .path = "data/renpy/images/ch/cat.dds" }, // 5 ch/cat.png
|
||||
{ .path = "data/renpy/images/ch/catw.dds" }, // 6 ch/catw.png
|
||||
{ .path = "data/renpy/images/ch/Eily.dds" }, // 7 ch/Eily.png
|
||||
{ .path = "data/renpy/images/ch/Alice.dds" }, // 8 ch/Alice.png
|
||||
};
|
||||
|
||||
const int images_length = (sizeof (images)) / (sizeof (images[0]));
|
||||
|
||||
const language::option options[] = {
|
||||
{ .string = "Complain", .statementIndex = 18 }, // 0
|
||||
{ .string = "Rationalize", .statementIndex = 26 }, // 1
|
||||
{ .string = "Good idea", .statementIndex = 54 }, // 2
|
||||
{ .string = "I am too tired", .statementIndex = 61 }, // 3
|
||||
{ .string = "Beg for mercy", .statementIndex = 78 }, // 4
|
||||
{ .string = "Run", .statementIndex = 80 }, // 5
|
||||
};
|
||||
|
||||
const int options_length = (sizeof (options)) / (sizeof (options[0]));
|
||||
|
||||
const language::statement statements[] = {
|
||||
{ .type = type::play, .play = { .audioIndex = 0, /* FIXME channel */ } }, // 0 sfx/Chime.ogg
|
||||
{ .type = type::play, .play = { .audioIndex = 1, /* FIXME channel */ } }, // 1 sfx/MistAmbience.ogg
|
||||
{ .type = type::scene_color, .scene_color = { .color = 0xffffff } }, // 2 bgwhite
|
||||
{ .type = type::dissolve, .dissolve = { .duration = 3.0 } }, // 3
|
||||
{ .type = type::say, .say = { .characterIndex = 4, .stringIndex = 0 } }, // 4 n "Far over the mountains of Almystice"
|
||||
{ .type = type::say, .say = { .characterIndex = 4, .stringIndex = 1 } }, // 5 n "Beyond the tumultuous waters of the Lilac Bay"
|
||||
{ .type = type::say, .say = { .characterIndex = 4, .stringIndex = 2 } }, // 6 n "And across the vast fields of Alysen"
|
||||
{ .type = type::play, .play = { .audioIndex = 2, /* FIXME channel */ } }, // 7 music/TinyForestMinstrels.ogg
|
||||
{ .type = type::say, .say = { .characterIndex = 4, .stringIndex = 3 } }, // 8 n "Tiny minstrels can be heard amongst the trees"
|
||||
{ .type = type::scene, .scene = { .imageIndex = 1 } }, // 9 bgforest1
|
||||
{ .type = type::dissolve, .dissolve = { .duration = 3.0 } }, // 10
|
||||
{ .type = type::show, .show = { .imageIndex = 8, .transformIndex = transform::left } }, // 11 al
|
||||
{ .type = type::say, .say = { .characterIndex = 0, .stringIndex = 4 } }, // 12 a "Are we almost there?"
|
||||
{ .type = type::show, .show = { .imageIndex = 7, .transformIndex = transform::right } }, // 13 ei
|
||||
{ .type = type::say, .say = { .characterIndex = 2, .stringIndex = 5 } }, // 14 e "Hmmm... Not really"
|
||||
{ .type = type::say, .say = { .characterIndex = 0, .stringIndex = 6 } }, // 15 a "How much further have we to go?"
|
||||
{ .type = type::say, .say = { .characterIndex = 2, .stringIndex = 7 } }, // 16 e "About two more moons"
|
||||
{ .type = type::menu, .menu = { .count = 2, .optionIndex = 0 } }, // 17 "Complain", "Rationalize"
|
||||
{ .type = type::say, .say = { .characterIndex = 0, .stringIndex = 8 } }, // 18 a "We are still sooo far awayyy"
|
||||
{ .type = type::say, .say = { .characterIndex = 2, .stringIndex = 9 } }, // 19 e "And it will be even further if you dont stop complaining"
|
||||
{ .type = type::say, .say = { .characterIndex = 0, .stringIndex = 10 } }, // 20 a "Easy for you to say, all you have to carry is a little memory pipe!"
|
||||
{ .type = type::say, .say = { .characterIndex = 0, .stringIndex = 11 } }, // 21 a "I'm tired ><"
|
||||
{ .type = type::say, .say = { .characterIndex = 2, .stringIndex = 12 } }, // 22 e "Don't start whining now!"
|
||||
{ .type = type::say, .say = { .characterIndex = 2, .stringIndex = 13 } }, // 23 e "You need to remember why we have come all this way"
|
||||
{ .type = type::say, .say = { .characterIndex = 0, .stringIndex = 14 } }, // 24 a "I understand... I suppose it is for an important purpose"
|
||||
{ .type = type::jump, .jump = { .statementIndex = 28 } }, // 25 internal jump (b'__menu_end', 0)
|
||||
{ .type = type::say, .say = { .characterIndex = 0, .stringIndex = 14 } }, // 26 a "I understand... I suppose it is for an important purpose"
|
||||
{ .type = type::jump, .jump = { .statementIndex = 28 } }, // 27 internal jump (b'__menu_end', 0)
|
||||
{ .type = type::jump, .jump = { .statementIndex = 29 } }, // 28 mainbranch1
|
||||
{ .type = type::say, .say = { .characterIndex = 2, .stringIndex = 15 } }, // 29 e "We're almost out of the forest, we can take a little break once we clear the tree line"
|
||||
{ .type = type::say, .say = { .characterIndex = 0, .stringIndex = 16 } }, // 30 a "Is that where the flora field is?"
|
||||
{ .type = type::say, .say = { .characterIndex = 2, .stringIndex = 17 } }, // 31 e "Why yes, If I remember correctly, it should be just up ahead"
|
||||
{ .type = type::stop, .stop = { /* FIXME channel */ } }, // 32
|
||||
{ .type = type::scene_color, .scene_color = { .color = 0xffffff } }, // 33 bgwhite
|
||||
{ .type = type::play, .play = { .audioIndex = 0, /* FIXME channel */ } }, // 34 sfx/Chime.ogg
|
||||
{ .type = type::dissolve, .dissolve = { .duration = 1.0 } }, // 35
|
||||
{ .type = type::voice, .voice = { .audioIndex = 3 } }, // 36 n5test.ogg
|
||||
{ .type = type::say, .say = { .characterIndex = 4, .stringIndex = 18 } }, // 37 n "As the minstrel mice girls continue along the path, the forest opens up into a beautiful field of flowers"
|
||||
{ .type = type::play, .play = { .audioIndex = 4, /* FIXME channel */ } }, // 38 music/PhrygianButterflies.ogg
|
||||
{ .type = type::scene, .scene = { .imageIndex = 3 } }, // 39 bgflower1
|
||||
{ .type = type::dissolve, .dissolve = { .duration = 1.0 } }, // 40
|
||||
{ .type = type::show, .show = { .imageIndex = 7, .transformIndex = transform::right } }, // 41 ei
|
||||
{ .type = type::say, .say = { .characterIndex = 2, .stringIndex = 19 } }, // 42 e "Look at all the butterflies! They are all so pretty!"
|
||||
{ .type = type::show, .show = { .imageIndex = 8, .transformIndex = transform::left } }, // 43 al
|
||||
{ .type = type::say, .say = { .characterIndex = 0, .stringIndex = 20 } }, // 44 a "This place is like a dream..."
|
||||
{ .type = type::say, .say = { .characterIndex = 2, .stringIndex = 21 } }, // 45 e "There are so many flowers this time of year"
|
||||
{ .type = type::say, .say = { .characterIndex = 2, .stringIndex = 22 } }, // 46 e "I told you it would be worth the journey!"
|
||||
{ .type = type::say, .say = { .characterIndex = 0, .stringIndex = 23 } }, // 47 a "Can we stop for a bit now?"
|
||||
{ .type = type::say, .say = { .characterIndex = 2, .stringIndex = 24 } }, // 48 e "Of course"
|
||||
{ .type = type::say, .say = { .characterIndex = 2, .stringIndex = 25 } }, // 49 e "Ya know, Its a shame we didnt save some of those giant strawberries you found"
|
||||
{ .type = type::say, .say = { .characterIndex = 0, .stringIndex = 26 } }, // 50 a "I told you not to eat them all!"
|
||||
{ .type = type::say, .say = { .characterIndex = 2, .stringIndex = 27 } }, // 51 e "Yah yah"
|
||||
{ .type = type::say, .say = { .characterIndex = 2, .stringIndex = 28 } }, // 52 e "Anyways, shall I recite a tale?"
|
||||
{ .type = type::menu, .menu = { .count = 2, .optionIndex = 2 } }, // 53 "Good idea", "I am too tired"
|
||||
{ .type = type::stop, .stop = { /* FIXME channel */ } }, // 54
|
||||
{ .type = type::say, .say = { .characterIndex = 0, .stringIndex = 29 } }, // 55 a "Why dont you sing the story of Eleanor the Hero!"
|
||||
{ .type = type::say, .say = { .characterIndex = 2, .stringIndex = 30 } }, // 56 e "Sure"
|
||||
{ .type = type::say, .say = { .characterIndex = 0, .stringIndex = 31 } }, // 57 a "..."
|
||||
{ .type = type::play, .play = { .audioIndex = 5, /* FIXME channel */ } }, // 58 music/Poem1.ogg
|
||||
{ .type = type::pause, .pause = { .duration = 40 } }, // 59
|
||||
{ .type = type::jump, .jump = { .statementIndex = 65 } }, // 60 internal jump (b'__menu_end', 1)
|
||||
{ .type = type::say, .say = { .characterIndex = 2, .stringIndex = 32 } }, // 61 e "Serves you right for scaring those elephant-dogs"
|
||||
{ .type = type::stop, .stop = { /* FIXME channel */ } }, // 62
|
||||
{ .type = type::say, .say = { .characterIndex = 0, .stringIndex = 33 } }, // 63 a "They were asking for it, you know"
|
||||
{ .type = type::jump, .jump = { .statementIndex = 65 } }, // 64 internal jump (b'__menu_end', 1)
|
||||
{ .type = type::jump, .jump = { .statementIndex = 66 } }, // 65 mainbranch2
|
||||
{ .type = type::hide, .hide = { .imageIndex = 7 } }, // 66 ei
|
||||
{ .type = type::show, .show = { .imageIndex = 6, .transformIndex = transform::right } }, // 67 catw
|
||||
{ .type = type::show, .show = { .imageIndex = 7, .transformIndex = transform::centerleft } }, // 68 ei
|
||||
{ .type = type::voice, .voice = { .audioIndex = 6 } }, // 69 placeholdermeow.mp3
|
||||
{ .type = type::say, .say = { .characterIndex = 1, .stringIndex = 34 } }, // 70 c "Rawrrrr"
|
||||
{ .type = type::hide, .hide = { .imageIndex = 6 } }, // 71 catw
|
||||
{ .type = type::show, .show = { .imageIndex = 5, .transformIndex = transform::right } }, // 72 cat
|
||||
{ .type = type::play, .play = { .audioIndex = 7, /* FIXME channel */ } }, // 73 music/ScaredMice.ogg
|
||||
{ .type = type::say, .say = { .characterIndex = 3, .stringIndex = 35 } }, // 74 mg "AHHHHHHHHHH!!!!!"
|
||||
{ .type = type::say, .say = { .characterIndex = 1, .stringIndex = 36 } }, // 75 c "Nyanyanyanya"
|
||||
{ .type = type::say, .say = { .characterIndex = 1, .stringIndex = 37 } }, // 76 c "Well, what do we have here? If it isn't two little meowse girls, all alone amongst the flowers"
|
||||
{ .type = type::menu, .menu = { .count = 2, .optionIndex = 4 } }, // 77 "Beg for mercy", "Run"
|
||||
{ .type = type::say, .say = { .characterIndex = 0, .stringIndex = 38 } }, // 78 a "Please don't eat us!!!"
|
||||
{ .type = type::jump, .jump = { .statementIndex = 83 } }, // 79 internal jump (b'__menu_end', 2)
|
||||
{ .type = type::say, .say = { .characterIndex = 2, .stringIndex = 39 } }, // 80 e "Alice don't run, our only chance is through pleading!"
|
||||
{ .type = type::say, .say = { .characterIndex = 2, .stringIndex = 40 } }, // 81 e "Please don't eat us, miss kitty cat!!! ><"
|
||||
{ .type = type::jump, .jump = { .statementIndex = 83 } }, // 82 internal jump (b'__menu_end', 2)
|
||||
{ .type = type::jump, .jump = { .statementIndex = 84 } }, // 83 mainbranch3
|
||||
{ .type = type::stop, .stop = { /* FIXME channel */ } }, // 84
|
||||
{ .type = type::say, .say = { .characterIndex = 1, .stringIndex = 41 } }, // 85 c "I'm not gonna eat you nyanyanya"
|
||||
{ .type = type::play, .play = { .audioIndex = 2, /* FIXME channel */ } }, // 86 music/TinyForestMinstrels.ogg
|
||||
{ .type = type::say, .say = { .characterIndex = 1, .stringIndex = 42 } }, // 87 c "I just want to know what two little meowses are doing so very far away from home"
|
||||
{ .type = type::say, .say = { .characterIndex = 1, .stringIndex = 43 } }, // 88 c "Also, are you minstrels?"
|
||||
{ .type = type::say, .say = { .characterIndex = 2, .stringIndex = 44 } }, // 89 e "Y-Yes"
|
||||
{ .type = type::say, .say = { .characterIndex = 0, .stringIndex = 45 } }, // 90 a "W-We are on a quest to Castle Alysen..."
|
||||
{ .type = type::say, .say = { .characterIndex = 2, .stringIndex = 46 } }, // 91 e "Shh don't tell her that"
|
||||
{ .type = type::say, .say = { .characterIndex = 1, .stringIndex = 47 } }, // 92 c "The Castle of Alysen you say?!?"
|
||||
{ .type = type::say, .say = { .characterIndex = 1, .stringIndex = 48 } }, // 93 c "Why, that's where I am headed!"
|
||||
{ .type = type::say, .say = { .characterIndex = 2, .stringIndex = 49 } }, // 94 e "You don't say..."
|
||||
{ .type = type::say, .say = { .characterIndex = 1, .stringIndex = 50 } }, // 95 c "Yah, I do actually"
|
||||
{ .type = type::say, .say = { .characterIndex = 2, .stringIndex = 51 } }, // 96 e "So... Why might you be traveling to the castle?"
|
||||
{ .type = type::say, .say = { .characterIndex = 1, .stringIndex = 52 } }, // 97 c "I belong to the lineage of Agrepen"
|
||||
{ .type = type::say, .say = { .characterIndex = 2, .stringIndex = 53 } }, // 98 e "And what might that mean?"
|
||||
{ .type = type::say, .say = { .characterIndex = 1, .stringIndex = 54 } }, // 99 c "The Agrepens are a long line of felines loyal to the crown of corvidae"
|
||||
{ .type = type::say, .say = { .characterIndex = 2, .stringIndex = 55 } }, // 100 e "Really? That must mean you are a noble?"
|
||||
{ .type = type::say, .say = { .characterIndex = 1, .stringIndex = 56 } }, // 101 c "Well, not really..."
|
||||
{ .type = type::say, .say = { .characterIndex = 1, .stringIndex = 57 } }, // 102 c "My father was one of the queens knights many years ago"
|
||||
{ .type = type::say, .say = { .characterIndex = 2, .stringIndex = 58 } }, // 103 e "Ah I see"
|
||||
{ .type = type::say, .say = { .characterIndex = 2, .stringIndex = 59 } }, // 104 e "So do you live at the castle or something?"
|
||||
{ .type = type::say, .say = { .characterIndex = 1, .stringIndex = 60 } }, // 105 c "Well, no..."
|
||||
{ .type = type::say, .say = { .characterIndex = 0, .stringIndex = 61 } }, // 106 a "Then why are you traveling to Castle Alysen?"
|
||||
{ .type = type::say, .say = { .characterIndex = 1, .stringIndex = 62 } }, // 107 c "uhhh"
|
||||
{ .type = type::play, .play = { .audioIndex = 1, /* FIXME channel */ } }, // 108 sfx/MistAmbience.ogg
|
||||
{ .type = type::stop, .stop = { /* FIXME channel */ } }, // 109
|
||||
{ .type = type::say, .say = { .characterIndex = 1, .stringIndex = 63 } }, // 110 c "I DONT NEED TO BE PRESSURED BY LITTLE MICE TO SAY ANYTHING!!!!"
|
||||
{ .type = type::say, .say = { .characterIndex = 1, .stringIndex = 64 } }, // 111 c "GOOD DAY!"
|
||||
{ .type = type::hide, .hide = { .imageIndex = 5 } }, // 112 cat
|
||||
{ .type = type::say, .say = { .characterIndex = 0, .stringIndex = 65 } }, // 113 a "Wha..."
|
||||
{ .type = type::say, .say = { .characterIndex = 2, .stringIndex = 66 } }, // 114 e "Phew, I was scared she was gonna follow us the whole way"
|
||||
{ .type = type::say, .say = { .characterIndex = 0, .stringIndex = 67 } }, // 115 a "She didn't seem so bad"
|
||||
{ .type = type::say, .say = { .characterIndex = 2, .stringIndex = 68 } }, // 116 e "Are you kidding? She's a crazy kitty!"
|
||||
{ .type = type::scene_color, .scene_color = { .color = 0xffffff } }, // 117 bgwhite
|
||||
{ .type = type::play, .play = { .audioIndex = 0, /* FIXME channel */ } }, // 118 sfx/Chime.ogg
|
||||
{ .type = type::dissolve, .dissolve = { .duration = 3.0 } }, // 119
|
||||
{ .type = type::say, .say = { .characterIndex = 4, .stringIndex = 69 } }, // 120 n "After their encounter with the weird cat, the mice scurry out of the flower field and into the nearby meadow"
|
||||
{ .type = type::scene, .scene = { .imageIndex = 2 } }, // 121 bgforest2
|
||||
{ .type = type::dissolve, .dissolve = { .duration = 3.0 } }, // 122
|
||||
{ .type = type::show, .show = { .imageIndex = 7, .transformIndex = transform::right } }, // 123 ei
|
||||
{ .type = type::say, .say = { .characterIndex = 2, .stringIndex = 70 } }, // 124 e "I think this is the right way..."
|
||||
{ .type = type::show, .show = { .imageIndex = 8, .transformIndex = transform::left } }, // 125 al
|
||||
{ .type = type::say, .say = { .characterIndex = 0, .stringIndex = 71 } }, // 126 a "Then where did the path go?"
|
||||
{ .type = type::say, .say = { .characterIndex = 2, .stringIndex = 72 } }, // 127 e "How am I supposed to know?"
|
||||
{ .type = type::say, .say = { .characterIndex = 0, .stringIndex = 73 } }, // 128 a "Did you hear that?!?!"
|
||||
{ .type = type::show, .show = { .imageIndex = 7, .transformIndex = transform::centerleft } }, // 129 ei
|
||||
{ .type = type::show, .show = { .imageIndex = 5, .transformIndex = transform::right } }, // 130 cat
|
||||
{ .type = type::play, .play = { .audioIndex = 4, /* FIXME channel */ } }, // 131 music/PhrygianButterflies.ogg
|
||||
{ .type = type::say, .say = { .characterIndex = 1, .stringIndex = 74 } }, // 132 c "Hey there..."
|
||||
{ .type = type::say, .say = { .characterIndex = 1, .stringIndex = 75 } }, // 133 c "I apologize"
|
||||
{ .type = type::say, .say = { .characterIndex = 1, .stringIndex = 76 } }, // 134 c "I didn't mean to storm off like that"
|
||||
{ .type = type::say, .say = { .characterIndex = 2, .stringIndex = 77 } }, // 135 e "Ha ha, no problem..."
|
||||
{ .type = type::say, .say = { .characterIndex = 0, .stringIndex = 78 } }, // 136 a "So... Why are you traveling to Castle Alysen?"
|
||||
{ .type = type::say, .say = { .characterIndex = 2, .stringIndex = 79 } }, // 137 e "Alice!!!"
|
||||
{ .type = type::say, .say = { .characterIndex = 1, .stringIndex = 80 } }, // 138 c "If you must know, I have been summoned by the queen"
|
||||
{ .type = type::say, .say = { .characterIndex = 1, .stringIndex = 81 } }, // 139 c "I suspect that my poor reputation amongst the locals of Eastern Nidus has come back to haunt me"
|
||||
{ .type = type::say, .say = { .characterIndex = 1, .stringIndex = 82 } }, // 140 c "Though I know not what what she has summoned me for"
|
||||
{ .type = type::say, .say = { .characterIndex = 0, .stringIndex = 83 } }, // 141 a "Ahhhhhh"
|
||||
{ .type = type::say, .say = { .characterIndex = 1, .stringIndex = 84 } }, // 142 c "So then..."
|
||||
{ .type = type::say, .say = { .characterIndex = 1, .stringIndex = 85 } }, // 143 c "Why are YOU traveling to the Castle?"
|
||||
{ .type = type::say, .say = { .characterIndex = 0, .stringIndex = 86 } }, // 144 a "We are delivering a feather!!!"
|
||||
{ .type = type::say, .say = { .characterIndex = 2, .stringIndex = 87 } }, // 145 e "Alice no!"
|
||||
{ .type = type::say, .say = { .characterIndex = 0, .stringIndex = 88 } }, // 146 a "A feather that belonged to the queen herself!!!"
|
||||
{ .type = type::say, .say = { .characterIndex = 2, .stringIndex = 89 } }, // 147 e "Why you little..."
|
||||
{ .type = type::say, .say = { .characterIndex = 1, .stringIndex = 90 } }, // 148 c "A feather you say? One of the queens?"
|
||||
{ .type = type::say, .say = { .characterIndex = 1, .stringIndex = 91 } }, // 149 c "How on the face of Al Mot might you have aquired such a thing?"
|
||||
{ .type = type::say, .say = { .characterIndex = 1, .stringIndex = 92 } }, // 150 c "If it is authentic, that is..."
|
||||
{ .type = type::say, .say = { .characterIndex = 2, .stringIndex = 93 } }, // 151 e "Since Alice cannot keep a secret, I shall tell you"
|
||||
{ .type = type::say, .say = { .characterIndex = 2, .stringIndex = 94 } }, // 152 e "Seven moons ago, our town was attacked by three owls and a band of mice from the northern principalities"
|
||||
{ .type = type::say, .say = { .characterIndex = 2, .stringIndex = 95 } }, // 153 e "Eventually word spread to greater nearby settlements, and so"
|
||||
{ .type = type::say, .say = { .characterIndex = 2, .stringIndex = 96 } }, // 154 e "Messengers from the keep in Musia sent for aid from the Ravens"
|
||||
{ .type = type::say, .say = { .characterIndex = 2, .stringIndex = 97 } }, // 155 e "Four moons ago, the request was answered"
|
||||
{ .type = type::say, .say = { .characterIndex = 2, .stringIndex = 98 } }, // 156 e "And a small group of mice accompanied by two ravens a fox, and three squirrels set out to the northern principalities"
|
||||
{ .type = type::say, .say = { .characterIndex = 2, .stringIndex = 99 } }, // 157 e "Anyways, long story short, we drove those barbaric rats out of their home"
|
||||
{ .type = type::say, .say = { .characterIndex = 0, .stringIndex = 100 } }, // 158 a "They arent actual rats you know"
|
||||
{ .type = type::say, .say = { .characterIndex = 2, .stringIndex = 101 } }, // 159 e "Obviously, but you wont catch me speaking kindly of them"
|
||||
{ .type = type::say, .say = { .characterIndex = 0, .stringIndex = 102 } }, // 160 a "And you forgot the most important part"
|
||||
{ .type = type::say, .say = { .characterIndex = 2, .stringIndex = 103 } }, // 161 e "Yah yah, I am getting there"
|
||||
{ .type = type::say, .say = { .characterIndex = 2, .stringIndex = 104 } }, // 162 e "So, essentially, my brother is trained in archery, and..."
|
||||
{ .type = type::say, .say = { .characterIndex = 0, .stringIndex = 105 } }, // 163 a "Speed it up already"
|
||||
{ .type = type::say, .say = { .characterIndex = 2, .stringIndex = 106 } }, // 164 e "You tell it then!"
|
||||
{ .type = type::say, .say = { .characterIndex = 0, .stringIndex = 107 } }, // 165 a "My cousin found this feather in one of the highest towers of a castle far to the north"
|
||||
{ .type = type::say, .say = { .characterIndex = 1, .stringIndex = 108 } }, // 166 c "How do you know it belongs to the queen?"
|
||||
{ .type = type::say, .say = { .characterIndex = 2, .stringIndex = 109 } }, // 167 e "It said so itself above the display on the wall"
|
||||
{ .type = type::say, .say = { .characterIndex = 0, .stringIndex = 110 } }, // 168 a "Supposedly, it was in a room filled with treasures!"
|
||||
{ .type = type::say, .say = { .characterIndex = 1, .stringIndex = 111 } }, // 169 c "That is very nice and all, but what are the two of you doing out here all alone?"
|
||||
{ .type = type::say, .say = { .characterIndex = 1, .stringIndex = 112 } }, // 170 c "Do you expect every bird in Avia to respect your alliance with Castle Alysen?"
|
||||
{ .type = type::say, .say = { .characterIndex = 2, .stringIndex = 113 } }, // 171 e "What do you mean?"
|
||||
{ .type = type::say, .say = { .characterIndex = 1, .stringIndex = 114 } }, // 172 c "I mean, the two of you probably look like walking dinner to most creatures"
|
||||
{ .type = type::say, .say = { .characterIndex = 0, .stringIndex = 115 } }, // 173 a "I could go for some dinner..."
|
||||
{ .type = type::say, .say = { .characterIndex = 2, .stringIndex = 116 } }, // 174 e "Anyways..."
|
||||
{ .type = type::say, .say = { .characterIndex = 2, .stringIndex = 117 } }, // 175 e "To answer your question, upon returning to the village, the feather was taken from my brother by the needle guild"
|
||||
{ .type = type::say, .say = { .characterIndex = 2, .stringIndex = 118 } }, // 176 e "So... Yesterday, after sundown"
|
||||
{ .type = type::say, .say = { .characterIndex = 2, .stringIndex = 119 } }, // 177 e "We stole the feather from the guild hall before vanishing into the night"
|
||||
{ .type = type::say, .say = { .characterIndex = 2, .stringIndex = 120 } }, // 178 e "Can you imagine the look on their stupid faces, when they woke up, and not only is the feather missing"
|
||||
{ .type = type::say, .say = { .characterIndex = 2, .stringIndex = 121 } }, // 179 e "But so are we!"
|
||||
{ .type = type::say, .say = { .characterIndex = 0, .stringIndex = 122 } }, // 180 a "Hahahaha"
|
||||
{ .type = type::say, .say = { .characterIndex = 1, .stringIndex = 123 } }, // 181 c "Are the two of you mad?"
|
||||
{ .type = type::say, .say = { .characterIndex = 1, .stringIndex = 124 } }, // 182 c "I assume you are attempting to return the Queens feather?"
|
||||
{ .type = type::say, .say = { .characterIndex = 0, .stringIndex = 125 } }, // 183 a "Yes, we intend to deliver the feather to its rightful owner"
|
||||
{ .type = type::say, .say = { .characterIndex = 1, .stringIndex = 126 } }, // 184 c "Absolute madness!"
|
||||
{ .type = type::say, .say = { .characterIndex = 3, .stringIndex = 31 } }, // 185 mg "..."
|
||||
{ .type = type::say, .say = { .characterIndex = 1, .stringIndex = 127 } }, // 186 c "I will follow the two of you"
|
||||
{ .type = type::say, .say = { .characterIndex = 1, .stringIndex = 128 } }, // 187 c "To keep you safe, that is"
|
||||
{ .type = type::say, .say = { .characterIndex = 0, .stringIndex = 129 } }, // 188 a "Alright!"
|
||||
{ .type = type::say, .say = { .characterIndex = 2, .stringIndex = 130 } }, // 189 e "Ha ha... Okay..."
|
||||
{ .type = type::say, .say = { .characterIndex = 1, .stringIndex = 131 } }, // 190 c "Great! Follow me, I know a shortcut! :3"
|
||||
{ .type = type::hide, .hide = { .imageIndex = 5 } }, // 191 cat
|
||||
{ .type = type::say, .say = { .characterIndex = 0, .stringIndex = 132 } }, // 192 a "Sounds good!"
|
||||
{ .type = type::hide, .hide = { .imageIndex = 8 } }, // 193 al
|
||||
{ .type = type::stop, .stop = { /* FIXME channel */ } }, // 194
|
||||
{ .type = type::say, .say = { .characterIndex = 2, .stringIndex = 133 } }, // 195 e "Oh dear!"
|
||||
{ .type = type::hide, .hide = { .imageIndex = 7 } }, // 196 ei
|
||||
{ .type = type::scene_color, .scene_color = { .color = 0xffffff } }, // 197 bgwhite
|
||||
{ .type = type::play, .play = { .audioIndex = 0, /* FIXME channel */ } }, // 198 sfx/Chime.ogg
|
||||
{ .type = type::dissolve, .dissolve = { .duration = 2.0 } }, // 199
|
||||
{ .type = type::say, .say = { .characterIndex = 4, .stringIndex = 134 } }, // 200 n "And so the mice girls follow the noble cat further towards their destination"
|
||||
{ .type = type::scene, .scene = { .imageIndex = 4 } }, // 201 bgwheatfield1
|
||||
{ .type = type::play, .play = { .audioIndex = 8, /* FIXME channel */ } }, // 202 music/WheatFields.ogg
|
||||
{ .type = type::show, .show = { .imageIndex = 5, .transformIndex = transform::right } }, // 203 cat
|
||||
{ .type = type::dissolve, .dissolve = { .duration = 1.3 } }, // 204
|
||||
{ .type = type::say, .say = { .characterIndex = 1, .stringIndex = 135 } }, // 205 c "Nya"
|
||||
{ .type = type::show, .show = { .imageIndex = 8, .transformIndex = transform::left } }, // 206 al
|
||||
{ .type = type::say, .say = { .characterIndex = 0, .stringIndex = 136 } }, // 207 a "Look, your right, the castle is just up ahead!"
|
||||
{ .type = type::show, .show = { .imageIndex = 7, .transformIndex = transform::centerleft } }, // 208 ei
|
||||
{ .type = type::say, .say = { .characterIndex = 2, .stringIndex = 137 } }, // 209 e "Wait up"
|
||||
{ .type = type::say, .say = { .characterIndex = 1, .stringIndex = 138 } }, // 210 c "I told you I knew a shortcut!"
|
||||
{ .type = type::say, .say = { .characterIndex = 1, .stringIndex = 139 } }, // 211 c "Most people take the long way around"
|
||||
{ .type = type::say, .say = { .characterIndex = 2, .stringIndex = 140 } }, // 212 e "Yah because these are royal wheatfields!"
|
||||
{ .type = type::say, .say = { .characterIndex = 0, .stringIndex = 141 } }, // 213 a "Who cares?"
|
||||
{ .type = type::say, .say = { .characterIndex = 2, .stringIndex = 142 } }, // 214 e "Are you trying to get us killed?"
|
||||
{ .type = type::say, .say = { .characterIndex = 2, .stringIndex = 143 } }, // 215 e "Its trespassing on royal land!"
|
||||
{ .type = type::say, .say = { .characterIndex = 1, .stringIndex = 144 } }, // 216 c "Calm down, I have done this a million times"
|
||||
{ .type = type::say, .say = { .characterIndex = 2, .stringIndex = 145 } }, // 217 e "That doesnt make me calm!"
|
||||
{ .type = type::say, .say = { .characterIndex = 1, .stringIndex = 146 } }, // 218 c "How can the rolling fields of wheat not calm your spirit?"
|
||||
{ .type = type::say, .say = { .characterIndex = 1, .stringIndex = 147 } }, // 219 c "You little mice truly are mad!"
|
||||
{ .type = type::say, .say = { .characterIndex = 0, .stringIndex = 148 } }, // 220 a "I like the wheat!"
|
||||
{ .type = type::say, .say = { .characterIndex = 2, .stringIndex = 149 } }, // 221 e "Shut up!"
|
||||
{ .type = type::say, .say = { .characterIndex = 1, .stringIndex = 150 } }, // 222 c "Sounds like someone needs a nap!"
|
||||
{ .type = type::say, .say = { .characterIndex = 2, .stringIndex = 151 } }, // 223 e "Why? because I'm not insane like you?"
|
||||
{ .type = type::say, .say = { .characterIndex = 1, .stringIndex = 152 } }, // 224 c "Yah, your so sane, that you decided to steal from your town and then run off alone to the country of birds"
|
||||
{ .type = type::say, .say = { .characterIndex = 1, .stringIndex = 153 } }, // 225 c "The power of friendship wont protect the two of you from becoming dinner"
|
||||
{ .type = type::say, .say = { .characterIndex = 1, .stringIndex = 154 } }, // 226 c "And that, is why I feel obligated to accompany you!"
|
||||
{ .type = type::say, .say = { .characterIndex = 2, .stringIndex = 155 } }, // 227 e "Hey, we have a good reason!"
|
||||
{ .type = type::say, .say = { .characterIndex = 1, .stringIndex = 156 } }, // 228 c "And what might that be?"
|
||||
{ .type = type::say, .say = { .characterIndex = 2, .stringIndex = 157 } }, // 229 e "My brother found the feather, not the town guild, its a matter of family pride!"
|
||||
{ .type = type::say, .say = { .characterIndex = 1, .stringIndex = 158 } }, // 230 c "Pride has touched the chosen meouse"
|
||||
{ .type = type::say, .say = { .characterIndex = 1, .stringIndex = 159 } }, // 231 c "Flies she towards the Castle"
|
||||
{ .type = type::say, .say = { .characterIndex = 1, .stringIndex = 160 } }, // 232 c "But her ambition burns far too bright, and silly myice dont have any wings to myelt"
|
||||
{ .type = type::say, .say = { .characterIndex = 3, .stringIndex = 161 } }, // 233 mg "What?"
|
||||
{ .type = type::say, .say = { .characterIndex = 1, .stringIndex = 162 } }, // 234 c "Nyanyanya"
|
||||
{ .type = type::say, .say = { .characterIndex = 1, .stringIndex = 163 } }, // 235 c "Nyevermind"
|
||||
{ .type = type::say, .say = { .characterIndex = 1, .stringIndex = 164 } }, // 236 c "Sing me a song little minstrels!"
|
||||
{ .type = type::say, .say = { .characterIndex = 1, .stringIndex = 165 } }, // 237 c "Very Nyice!"
|
||||
{ .type = type::say, .say = { .characterIndex = 1, .stringIndex = 166 } }, // 238 c "Now tell me little minstrels, what are your names?"
|
||||
{ .type = type::say, .say = { .characterIndex = 0, .stringIndex = 167 } }, // 239 a "My name is Alice"
|
||||
{ .type = type::say, .say = { .characterIndex = 2, .stringIndex = 168 } }, // 240 e "And my name is Eily"
|
||||
{ .type = type::say, .say = { .characterIndex = 2, .stringIndex = 169 } }, // 241 e "What is your name?"
|
||||
{ .type = type::say, .say = { .characterIndex = 5, .stringIndex = 170 } }, // 242 l "My name is Leona!"
|
||||
{ .type = type::scene_color, .scene_color = { .color = 0xffffff } }, // 243 bgwhite
|
||||
{ .type = type::dissolve, .dissolve = { .duration = 3.0 } }, // 244
|
||||
{ .type = type::say, .say = { .characterIndex = 4, .stringIndex = 171 } }, // 245 n "And so, the odd trio walked through the wheatfields and towards the castle walls"
|
||||
{ .type = type::say, .say = { .characterIndex = 4, .stringIndex = 172 } }, // 246 n "Upon approaching the castle walls"
|
||||
{ .type = type::_return }, // 247
|
||||
};
|
||||
|
||||
const int statements_length = (sizeof (statements)) / (sizeof (statements[0]));
|
||||
|
||||
}
|
||||
@ -1,613 +0,0 @@
|
||||
#include <string.h>
|
||||
|
||||
#include "volk/volk.h"
|
||||
#include "vulkan/vk_enum_string_helper.h"
|
||||
|
||||
#include "dds/validate.h"
|
||||
#include "vulkan_helper.h"
|
||||
#include "check.h"
|
||||
#include "new.h"
|
||||
#include "file.h"
|
||||
|
||||
#include "renpy/vulkan.h"
|
||||
#include "renpy/script.h"
|
||||
#include "renpy/interact.h"
|
||||
|
||||
namespace renpy {
|
||||
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();
|
||||
load_images();
|
||||
write_descriptor_sets();
|
||||
create_pipeline();
|
||||
create_instance_buffers();
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
// 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.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 = (uint32_t)script::images_length,
|
||||
},
|
||||
};
|
||||
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 = (uint32_t)script::images_length,
|
||||
.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()
|
||||
{
|
||||
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 = NewM<VkDescriptorImageInfo>(script::images_length);
|
||||
for (int i = 0; i < script::images_length; i++) {
|
||||
sceneDescriptorImageInfos[i] = {
|
||||
.imageView = images[i].imageView,
|
||||
.imageLayout = VK_IMAGE_LAYOUT_READ_ONLY_OPTIMAL
|
||||
};
|
||||
}
|
||||
|
||||
writeDescriptorSets[writeIndex++] = {
|
||||
.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET,
|
||||
.dstSet = descriptorSet0,
|
||||
.dstBinding = 1,
|
||||
.descriptorCount = (uint32_t)script::images_length,
|
||||
.descriptorType = VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE,
|
||||
.pImageInfo = sceneDescriptorImageInfos
|
||||
};
|
||||
|
||||
assert(writeIndex == writeCount);
|
||||
vkUpdateDescriptorSets(device, writeIndex, writeDescriptorSets, 0, nullptr);
|
||||
//free(sceneDescriptorImageInfos);
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
// images
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
|
||||
void vulkan::load_image_inner(VkCommandBuffer commandBuffer, VkFence fence, int i, char const * filename)
|
||||
{
|
||||
size_t length = strlen(filename);
|
||||
if (dds::isDDSExtension(filename, length)) {
|
||||
createImageFromFilenameDDS(device,
|
||||
queue,
|
||||
commandBuffer,
|
||||
fence,
|
||||
physicalDeviceProperties.limits.nonCoherentAtomSize,
|
||||
physicalDeviceMemoryProperties,
|
||||
filename,
|
||||
&images[i].image,
|
||||
&images[i].memory,
|
||||
&images[i].imageView);
|
||||
} else {
|
||||
fprintf(stderr, "filename: %s\n", filename);
|
||||
ASSERT(false, "invalid image filename extension");
|
||||
}
|
||||
}
|
||||
|
||||
void vulkan::load_images()
|
||||
{
|
||||
VkCommandBuffer commandBuffer{};
|
||||
VkCommandBufferAllocateInfo commandBufferAllocateInfo{
|
||||
.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO,
|
||||
.commandPool = commandPool,
|
||||
.commandBufferCount = 1
|
||||
};
|
||||
VK_CHECK(vkAllocateCommandBuffers(device, &commandBufferAllocateInfo, &commandBuffer));
|
||||
|
||||
VkFenceCreateInfo fenceCreateInfo{
|
||||
.sType = VK_STRUCTURE_TYPE_FENCE_CREATE_INFO
|
||||
};
|
||||
VkFence fence{};
|
||||
VK_CHECK(vkCreateFence(device, &fenceCreateInfo, nullptr, &fence));
|
||||
|
||||
// images
|
||||
images = NewM<Image>(script::images_length);
|
||||
|
||||
for (int i = 0; i < script::images_length; i++) {
|
||||
char const * filename = script::images[i].path;
|
||||
load_image_inner(commandBuffer, fence, i, filename);
|
||||
}
|
||||
|
||||
// cleanup
|
||||
|
||||
vkDestroyFence(device, fence, nullptr);
|
||||
vkFreeCommandBuffers(device,
|
||||
commandPool,
|
||||
1,
|
||||
&commandBuffer);
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
// create instance buffer
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
|
||||
void vulkan::create_instance_buffers()
|
||||
{
|
||||
constexpr VkDeviceSize bufferSize{ maximumImageCount * (sizeof (ImageInstance)) };
|
||||
instanceMemorySize = bufferSize * 2;
|
||||
instanceBufferOffset[0] = bufferSize * 0;
|
||||
instanceBufferOffset[1] = bufferSize * 1;
|
||||
|
||||
// create buffer
|
||||
VkBufferCreateInfo bufferCreateInfo{
|
||||
.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO,
|
||||
.size = instanceMemorySize,
|
||||
.usage = VK_BUFFER_USAGE_VERTEX_BUFFER_BIT,
|
||||
.sharingMode = VK_SHARING_MODE_EXCLUSIVE
|
||||
};
|
||||
VK_CHECK(vkCreateBuffer(device, &bufferCreateInfo, nullptr, &instanceBuffer));
|
||||
|
||||
// allocate memory
|
||||
|
||||
VkMemoryRequirements memoryRequirements;
|
||||
vkGetBufferMemoryRequirements(device, instanceBuffer, &memoryRequirements);
|
||||
VkMemoryPropertyFlags memoryPropertyFlags{ VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT };
|
||||
VkMemoryAllocateFlags memoryAllocateFlags{};
|
||||
VkDeviceSize stride;
|
||||
allocateFromMemoryRequirements(device,
|
||||
physicalDeviceProperties.limits.nonCoherentAtomSize,
|
||||
physicalDeviceMemoryProperties,
|
||||
memoryRequirements,
|
||||
memoryPropertyFlags,
|
||||
memoryAllocateFlags,
|
||||
1,
|
||||
&instanceMemory,
|
||||
&stride);
|
||||
|
||||
VK_CHECK(vkBindBufferMemory(device, instanceBuffer, instanceMemory, 0));
|
||||
|
||||
// map memory
|
||||
|
||||
VK_CHECK(vkMapMemory(device, instanceMemory, 0, VK_WHOLE_SIZE, 0, (void **)&instanceMappedData));
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
// pipeline
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
|
||||
void vulkan::create_pipeline()
|
||||
{
|
||||
VkPipelineLayoutCreateInfo pipelineLayoutCreateInfo{
|
||||
.sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO,
|
||||
.setLayoutCount = descriptorSetLayoutCount,
|
||||
.pSetLayouts = descriptorSetLayouts,
|
||||
.pushConstantRangeCount = 0,
|
||||
.pPushConstantRanges = nullptr
|
||||
};
|
||||
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_TRUE,
|
||||
.srcColorBlendFactor = VK_BLEND_FACTOR_SRC_ALPHA,
|
||||
.dstColorBlendFactor = VK_BLEND_FACTOR_ONE_MINUS_SRC_ALPHA,
|
||||
.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 = 2;
|
||||
VkVertexInputBindingDescription vertexBindingDescriptions[vertexBindingDescriptionsCount]{
|
||||
{
|
||||
.binding = 0,
|
||||
.stride = perVertexSize,
|
||||
.inputRate = VK_VERTEX_INPUT_RATE_VERTEX
|
||||
},
|
||||
{
|
||||
.binding = 1,
|
||||
.stride = perInstanceSize,
|
||||
.inputRate = VK_VERTEX_INPUT_RATE_INSTANCE
|
||||
},
|
||||
};
|
||||
|
||||
constexpr int vertexAttributeDescriptionsCount = 6;
|
||||
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,
|
||||
},
|
||||
// per-instance
|
||||
{
|
||||
.location = 2,
|
||||
.binding = 1,
|
||||
.format = VK_FORMAT_R16G16_SINT,
|
||||
.offset = 0,
|
||||
},
|
||||
{
|
||||
.location = 3,
|
||||
.binding = 1,
|
||||
.format = VK_FORMAT_R16G16_SINT,
|
||||
.offset = 4,
|
||||
},
|
||||
{
|
||||
.location = 4,
|
||||
.binding = 1,
|
||||
.format = VK_FORMAT_R8G8B8A8_UNORM,
|
||||
.offset = 8,
|
||||
},
|
||||
{
|
||||
.location = 5,
|
||||
.binding = 1,
|
||||
.format = VK_FORMAT_R16_SINT,
|
||||
.offset = 12,
|
||||
},
|
||||
};
|
||||
|
||||
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,
|
||||
renpy::interpreter const& state,
|
||||
int mx,
|
||||
int my)
|
||||
{
|
||||
int outputIndex = 0;
|
||||
// update
|
||||
instanceMappedData[maximumImageCount * frameIndex + outputIndex++] = {
|
||||
.size = {1280, 720},
|
||||
.topLeft = {0, 0},
|
||||
.color = state.backgroundColor,
|
||||
.imageIndex = (int16_t)state.backgroundIndex,
|
||||
};
|
||||
|
||||
for (uint32_t i = 0; i < state.shownImagesCount; i++) {
|
||||
renpy::top_left const& tl = renpy::transforms[state.shownImages[i].transformIndex];
|
||||
instanceMappedData[maximumImageCount * frameIndex + outputIndex++] = {
|
||||
.size = {452, 528},
|
||||
.topLeft = {(int16_t)tl.left, (int16_t)tl.top},
|
||||
.imageIndex = (int16_t)state.shownImages[i].imageIndex,
|
||||
};
|
||||
}
|
||||
|
||||
if (state.menu.count == 0) {
|
||||
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
|
||||
};
|
||||
}
|
||||
} 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
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
// flush
|
||||
constexpr int mappedMemoryRangesCount = 1;
|
||||
VkMappedMemoryRange mappedMemoryRanges[mappedMemoryRangesCount]{
|
||||
{
|
||||
.sType = VK_STRUCTURE_TYPE_MAPPED_MEMORY_RANGE,
|
||||
.memory = instanceMemory,
|
||||
.offset = 0,
|
||||
.size = (sizeof (ImageInstance)) * outputIndex,
|
||||
}
|
||||
};
|
||||
alignMappedMemoryRanges(physicalDeviceProperties.limits.nonCoherentAtomSize,
|
||||
instanceMemorySize,
|
||||
mappedMemoryRangesCount,
|
||||
mappedMemoryRanges);
|
||||
vkFlushMappedMemoryRanges(device, mappedMemoryRangesCount, mappedMemoryRanges);
|
||||
|
||||
// draw
|
||||
|
||||
vkCmdBindPipeline(commandBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, pipeline);
|
||||
|
||||
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[2]{ 0, instanceBufferOffset[frameIndex] };
|
||||
VkBuffer vertexBuffers[2]{ vertexIndex.buffer, instanceBuffer };
|
||||
vkCmdBindVertexBuffers(commandBuffer, 0, 2, vertexBuffers, vertexOffsets);
|
||||
|
||||
vkCmdDrawIndexed(commandBuffer, 4, outputIndex, 0, 0, 0);
|
||||
}
|
||||
}
|
||||