diff --git a/Makefile b/Makefile index 070b6f3..f224b7a 100644 --- a/Makefile +++ b/Makefile @@ -62,7 +62,8 @@ OBJS = \ src/font/outline.o \ src/renpy/vulkan.o \ src/renpy/script.o \ - src/renpy/interpreter.o + src/renpy/interpreter.o \ + src/renpy/interact.o WORLDS = \ data/minecraft/midnightmeadow/inthash.o \ diff --git a/include/renpy/interact.h b/include/renpy/interact.h new file mode 100644 index 0000000..b5f10a0 --- /dev/null +++ b/include/renpy/interact.h @@ -0,0 +1,17 @@ +#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); +} diff --git a/include/renpy/interpreter.h b/include/renpy/interpreter.h index d0018ad..674bc05 100644 --- a/include/renpy/interpreter.h +++ b/include/renpy/interpreter.h @@ -40,6 +40,7 @@ namespace renpy { uint32_t count; uint32_t optionIndex; } menu; + bool interactionWait; uint32_t findImage(uint32_t imageIndex); void showImage(uint32_t imageIndex, uint32_t transformIndex); diff --git a/include/renpy/vulkan.h b/include/renpy/vulkan.h index c8d78bd..17695dc 100644 --- a/include/renpy/vulkan.h +++ b/include/renpy/vulkan.h @@ -82,7 +82,9 @@ namespace renpy { void create_instance_buffers(); void draw(VkCommandBuffer commandBuffer, uint32_t frameIndex, - renpy::interpreter const& state); + renpy::interpreter const& state, + int mx, + int my); }; } diff --git a/shader/renpy.hlsl b/shader/renpy.hlsl index 843f48a..edd4298 100644 --- a/shader/renpy.hlsl +++ b/shader/renpy.hlsl @@ -34,7 +34,7 @@ VSOutput VSMain(VSInput input) output.Position = float4(position * 2.0 - 1.0, 0, 1); output.Texture = texture; output.TextureIndex = input.TextureIndex; - output.Color = input.Color; + output.Color = input.Color.zyxw; return output; } @@ -44,8 +44,8 @@ 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 * 0.5; - float3 color = float3(1.0, 1.0, 1.0); + float d = a * b * c * input.Color.w; + float3 color = input.Color.xyz; return float4(color, d); } @@ -53,8 +53,8 @@ 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 * 0.5; - float3 color = float3(1.0, 1.0, 1.0); + float d = a * b * input.Color.w; + float3 color = input.Color.xyz; return float4(color, d); } @@ -62,8 +62,8 @@ 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 * 0.5; - float3 color = float3(1.0, 1.0, 1.0); + float d = a * b * input.Color.w; + float3 color = input.Color.xyz; return float4(color, d); } diff --git a/src/main.cpp b/src/main.cpp index 385458f..0d93c37 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -23,6 +23,7 @@ #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" @@ -723,7 +724,6 @@ int main() renpy::interpreter interpreter_state; interpreter_state.reset(); - interpreter_state.interpret(); ////////////////////////////////////////////////////////////////////// // initialize view @@ -767,6 +767,8 @@ int main() //collada_state.update(0); while (quit == false) { + interpreter_state.interpret(); + SDL_Event event; while (SDL_PollEvent(&event)) { if (event.type == SDL_EVENT_QUIT) { @@ -1082,7 +1084,12 @@ int main() //minecraft_state.draw(commandBuffer, frameIndex); - renpy_state.draw(commandBuffer, frameIndex, interpreter_state); + 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); vkCmdEndRendering(commandBuffer); diff --git a/src/renpy/interact.cpp b/src/renpy/interact.cpp new file mode 100644 index 0000000..8c002c5 --- /dev/null +++ b/src/renpy/interact.cpp @@ -0,0 +1,47 @@ +#include +#include + +#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; + } + } + } +} diff --git a/src/renpy/interpreter.cpp b/src/renpy/interpreter.cpp index 2ba8f4f..e89d6b6 100644 --- a/src/renpy/interpreter.cpp +++ b/src/renpy/interpreter.cpp @@ -14,6 +14,7 @@ namespace renpy { say.stringIndex = -1; say.characterIndex = -1; menu.count = 0; + interactionWait = false; } uint32_t interpreter::findImage(uint32_t imageIndex) @@ -86,6 +87,7 @@ namespace renpy { 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: @@ -110,6 +112,11 @@ namespace renpy { 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; @@ -119,16 +126,13 @@ namespace renpy { void interpreter::interpret() { - while (true) { + while (!interactionWait) { + //while (true) { uint32_t last_pc = pc; interpret_one(); assert(pc != last_pc); - if (pc == 17) { - break; - } - //if (stop) - //break; + //if (pc == 18) break; } } }; diff --git a/src/renpy/vulkan.cpp b/src/renpy/vulkan.cpp index 22eedd2..32695f7 100644 --- a/src/renpy/vulkan.cpp +++ b/src/renpy/vulkan.cpp @@ -11,6 +11,7 @@ #include "renpy/vulkan.h" #include "renpy/script.h" +#include "renpy/interact.h" namespace renpy { static const _Float16 vertexData[] = { @@ -510,7 +511,9 @@ namespace renpy { void vulkan::draw(VkCommandBuffer commandBuffer, uint32_t frameIndex, - renpy::interpreter const& state) + renpy::interpreter const& state, + int mx, + int my) { int outputIndex = 0; // update @@ -534,6 +537,7 @@ namespace renpy { instanceMappedData[maximumImageCount * frameIndex + outputIndex++] = { .size = {708, 200}, .topLeft = {286, 720 - 200}, + .color = 0x80ffffffu, .imageIndex = -2, // white gradient 1 }; instanceMappedData[maximumImageCount * frameIndex + outputIndex++] = { @@ -551,14 +555,19 @@ namespace renpy { 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 = {480, 40}, - .topLeft = {400, (int16_t)(100 * i + 100)}, + .size = {menu::width, menu::height}, + .topLeft = {menu::x, (int16_t)(y)}, + .color = overlap ? 0xf0494493u : 0xa0ffffffu, .imageIndex = -3, // white gradient 2 }; }