overlap: support for window resize

This commit is contained in:
Zack Buhman 2026-05-29 22:43:23 -05:00
parent 5b645bd8ad
commit fb3c8b7a04
6 changed files with 61 additions and 26 deletions

View File

@ -12,6 +12,11 @@ namespace renpy {
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);
bool overlap(int menuWidth, int menuHeight,
int x, int y,
int mx, int my,
int windowWidth, int windowHeight);
void update(interpreter & state,
int mx, int my, bool mLeft,
int windowWidth, int windowHeight);
}

View File

@ -87,7 +87,9 @@ namespace renpy {
uint32_t frameIndex,
renpy::interpreter const& state,
int & outputIndex,
int mx, int my) const;
int mx, int my,
int windowWidth,
int windowHeight) const;
void draw_say_frame(VkCommandBuffer commandBuffer,
uint32_t frameIndex,
renpy::interpreter const& state,
@ -96,7 +98,9 @@ namespace renpy {
uint32_t frameIndex,
renpy::interpreter const& state,
int mx, int my,
bool drawText) const;
bool drawText,
int windowWidth,
int windowHeight) const;
};
}

View File

@ -36,12 +36,13 @@ VSOutput VSMain(VSInput input)
float2 canonicalSize = float2(1280, 720);
float2 size = float2(PushConstant.Width, PushConstant.Height);
while (canonicalSize.x * 2 <= size.x && canonicalSize.y * 2 <= size.y) {
canonicalSize *= 2;
int scaleFactor = 1;
while (canonicalSize.x * (scaleFactor + 1) <= size.x && canonicalSize.y * (scaleFactor + 1) <= size.y) {
scaleFactor += 1;
}
float2 inverseSize = 1.0 / size;
float2 scale = canonicalSize * inverseSize;
float2 scale = canonicalSize * scaleFactor * inverseSize;
output.Position = float4(input.Position * scale, 0, 1);
output.Texture = input.Texture;

View File

@ -368,7 +368,8 @@ void offscreenRender(VkCommandBuffer commandBuffer, int frameIndex,
int mx, int my, int colorIndex, bool drawText,
renpy::vulkan const & renpy_state,
renpy::interpreter const & interpreter_state,
font::outline::font const & font_state)
font::outline::font const & font_state,
VkSurfaceCapabilitiesKHR const & surfaceCapabilities)
{
// barrier
constexpr int colorBarriersCount = 2;
@ -466,7 +467,9 @@ void offscreenRender(VkCommandBuffer commandBuffer, int frameIndex,
//collada_state.vulkan.pipelineIndex = 0; // shadow pipeline
//collada_state.draw();
renpy_state.draw(commandBuffer, frameIndex, interpreter_state, mx, my, drawText);
renpy_state.draw(commandBuffer, frameIndex, interpreter_state,
mx, my, drawText,
surfaceCapabilities.currentExtent.width, surfaceCapabilities.currentExtent.height);
if (drawText) {
font_state.draw(commandBuffer, frameIndex, interpreter_state);
}
@ -954,7 +957,7 @@ int main()
//////////////////////////////////////////////////////////////////////
renpy::interpreter interpreter_state;
interpreter_state.reset(99);
interpreter_state.reset(27);
//////////////////////////////////////////////////////////////////////
// renpy composite
@ -1086,7 +1089,9 @@ int main()
float my;
uint32_t mouseFlags = SDL_GetMouseState(&mx, &my);
bool mLeft = (mouseFlags & SDL_BUTTON_LMASK) != 0;
renpy::update(interpreter_state, mx, my, mLeft);
renpy::update(interpreter_state, mx, my, mLeft,
surfaceCapabilities.currentExtent.width,
surfaceCapabilities.currentExtent.height);
//////////////////////////////////////////////////////////////////////
// gamepad update
@ -1272,10 +1277,10 @@ int main()
//////////////////////////////////////////////////////////////////////
if (interpreter_state.pause.dissolve) {
offscreenRender(commandBuffer, frameIndex, mx, my, 2, true, renpy_state, interpreter_state, font_state);
offscreenRender(commandBuffer, frameIndex, mx, my, 2, true, renpy_state, interpreter_state, font_state, surfaceCapabilities);
} else {
offscreenRender(commandBuffer, frameIndex, mx, my, 0, true, renpy_state, interpreter_state, font_state);
offscreenRender(commandBuffer, frameIndex, mx, my, 1, false, renpy_state, interpreter_state, font_state);
offscreenRender(commandBuffer, frameIndex, mx, my, 0, true, renpy_state, interpreter_state, font_state, surfaceCapabilities);
offscreenRender(commandBuffer, frameIndex, mx, my, 1, false, renpy_state, interpreter_state, font_state, surfaceCapabilities);
}
//////////////////////////////////////////////////////////////////////

View File

@ -5,19 +5,36 @@
#include "renpy/interact.h"
namespace renpy {
bool overlap(int width, int height, int x, int y, int mx, int my)
bool overlap(int menuWidth, int menuHeight,
int x, int y,
int mx, int my,
int windowWidth, int windowHeight)
{
int minX = x;
int minY = y;
int maxX = x + width;
int maxY = y + height;
float minX = x;
float minY = y;
float maxX = x + menuWidth;
float maxY = y + menuHeight;
return mx >= minX && mx <= maxX && my >= minY && my <= maxY;
int canonicalSizeX = 1280;
int canonicalSizeY = 720;
int scaleFactor = 1;
while (canonicalSizeX * (scaleFactor + 1) <= windowWidth && canonicalSizeY * (scaleFactor + 1) <= windowHeight) {
scaleFactor += 1;
}
float scaleFactorInverse = 1.0f / ((float)scaleFactor);
int offsetX = (windowWidth - (canonicalSizeX * scaleFactor)) / 2;
int offsetY = (windowHeight - (canonicalSizeY * scaleFactor)) / 2;
float mxf = ((float)(mx - offsetX)) * scaleFactorInverse;
float myf = ((float)(my - offsetY)) * scaleFactorInverse;
return mxf >= minX && mxf <= maxX && myf >= minY && myf <= maxY;
}
static bool lastmLeft = false;
void update(interpreter & state, int mx, int my, bool mLeft)
void update(interpreter & state,
int mx, int my, bool mLeft,
int windowWidth, int windowHeight)
{
bool mDown = mLeft && (!lastmLeft);
lastmLeft = mLeft;
@ -31,7 +48,7 @@ namespace renpy {
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);
bool overlap = renpy::overlap(menu::width, menu::height, menu::x, y, mx, my, windowWidth, windowHeight);
if (overlap) {
// jump to menu item
uint32_t optionIndex = state.menu.optionIndex + i;

View File

@ -527,13 +527,14 @@ namespace renpy {
uint32_t frameIndex,
renpy::interpreter const& state,
int & outputIndex,
int mx, int my) const
int mx, int my,
int windowWidth, int windowHeight) const
{
assert(state.menu.count != 0);
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);
bool overlap = renpy::overlap(menu::width, menu::height, menu::x, y, mx, my, windowWidth, windowHeight);
instanceMappedData[maximumImageCount * frameIndex + outputIndex++] = {
.size = {menu::width, menu::height},
.topLeft = {menu::x, (int16_t)(y)},
@ -579,7 +580,9 @@ namespace renpy {
uint32_t frameIndex,
renpy::interpreter const& state,
int mx, int my,
bool drawText) const
bool drawText,
int windowWidth,
int windowHeight) const
{
int outputIndex = 0;
// update
@ -607,7 +610,7 @@ namespace renpy {
if (drawText) {
if (state.pause.menu) {
draw_menu_frame(commandBuffer, frameIndex, state, outputIndex, mx, my);
draw_menu_frame(commandBuffer, frameIndex, state, outputIndex, mx, my, windowWidth, windowHeight);
} else if (state.say.stringIndex != ~0u) {
draw_say_frame(commandBuffer, frameIndex, state, outputIndex);
}