Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 16 additions & 2 deletions .github/workflows/build-euryopa.yml
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ permissions:

env:
LIBRW: ${{ github.workspace }}/librw
LIBRW_REF: 15ffa585216a9a7573ecc597b19ce2fde9b935f2
LIBRW_REF: 4456bb0d3c093c288388b9544253c78f3cbbe66d

jobs:
build-windows:
Expand Down Expand Up @@ -81,11 +81,25 @@ jobs:
working-directory: ariane/build
run: msbuild librwgta.sln /p:Configuration=Release /p:Platform=win-amd64-d3d9 /t:librwgta;euryopa /m

- name: Prepare Windows test artifact
shell: pwsh
working-directory: ariane
run: |
$exe = "bin/win-amd64-d3d9/Release/ariane.exe"
$hash = (Get-FileHash $exe -Algorithm SHA256).Hash.ToLower()
"$hash ariane.exe" | Set-Content "bin/win-amd64-d3d9/Release/ariane.exe.sha256"
Copy-Item "docs/testing/detached-panels.md" "bin/win-amd64-d3d9/Release/TESTING.md"

- name: Upload euryopa.exe
uses: actions/upload-artifact@v4
with:
name: ariane-windows-d3d9
path: ariane/bin/win-amd64-d3d9/Release/ariane.exe
path: |
ariane/bin/win-amd64-d3d9/Release/ariane.exe
ariane/bin/win-amd64-d3d9/Release/ariane.exe.sha256
ariane/bin/win-amd64-d3d9/Release/TESTING.md
if-no-files-found: error
retention-days: 14

- name: Create GitHub Release
if: github.event_name == 'push'
Expand Down
45 changes: 45 additions & 0 deletions docs/testing/detached-panels.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
# Windows detachable panels — tester checklist

This build enables native detached panels on Windows / Direct3D9. Drag the title
bar of **Window > View** beyond the main window, onto a second monitor. Drag it
fully back inside the main window to reattach. Other tool panels use the same
infrastructure. macOS/Linux keep their existing single-window behavior.

Use **Window > Bring panels back to main window** to recover misplaced panels.
Window positions are saved in the editor's existing `imgui.ini`.

## Acceptance checks

- Drag View, Time & Weather, Object Info and Object Browser out and back. Resize
and close a detached panel, then reopen it from Window. Closing a panel must
not close the editor.
- Change weather/rendering settings and numeric object properties in detached
panels. Verify the main scene updates and text editing does not move the camera
or trigger editor shortcuts. Check Ctrl+A/C/V and scrolling in text fields.
- Check Object Browser thumbnails and the rotating model preview on both screens.
- Move the main window to a different monitor, including one to the left or above
the primary monitor. Test translation/rotation, water gizmos, rectangle
selection, placement/brush markers and notification positions.
- Test monitors at 100%, 125%, 150% or 200% scaling. Text should remain readable,
and pointer hit targets should match their visible positions after moving.
- Repeatedly resize/maximize/restore the main window with panels detached. Alt+Tab
out and back, minimize/restore, and lock/unlock Windows. Look for crashes,
frozen panels, missing text, corrupted previews or changes in scene rendering.
- Restart with detached panels saved; disconnect/reconnect the second display and
try Bring panels back. Confirm every panel can be recovered.
- Close Ariane both via File > Exit and the native close button with panels open.

Report Windows version, GPU/driver, monitor arrangement/scaling, game, executable
SHA-256, reproduction steps, and a screenshot/video for each failure. A clean CI
build and static review do not replace these real multi-monitor checks.

## Implementation and build

Ariane's workflow pins the matching librw commit. That dependency contains ImGui
v1.92.2b-docking, the official Win32/DX9 backends with a librw texture-ID bridge,
and a device-resource release hook used before resets. The app enables these
backends only for its Windows D3D9 target. Use the `LIBRW_REF` from
`.github/workflows/build-euryopa.yml` when building locally.

PR/manual Actions runs produce the `ariane-windows-d3d9` artifact without creating
a public release. The ordinary release version is intentionally unchanged.
7 changes: 7 additions & 0 deletions premake5.lua
Original file line number Diff line number Diff line change
Expand Up @@ -289,6 +289,13 @@ project "euryopa"
kind "ConsoleApp"
filter {}
skeltool("euryopa")
filter { "system:windows", "platforms:*d3d9" }
removefiles { path.join(Librw, "skeleton/imgui/imgui_impl_rw.cpp") }
files { path.join(Librw, "skeleton/imgui/backends/imgui_impl_win32.cpp"),
path.join(Librw, "skeleton/imgui/backends/imgui_impl_dx9.cpp") }
includedirs { path.join(Librw, "skeleton/imgui") }
links { "dwmapi" }
filter {}
includedirs { "tools/euryopa" }
files { "tools/euryopa/minilzo/minilzo.c" }
removeplatforms { "*null" }
Expand Down
3 changes: 2 additions & 1 deletion tools/euryopa/WaterLevel.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1644,7 +1644,8 @@ DoWaterGizmo(void)
float *fview = (float*)&cam->devView;
float *fproj = (float*)&cam->devProj;

ImGuizmo::SetRect(0, 0, io.DisplaySize.x, io.DisplaySize.y);
ImVec2 origin = ImGui::GetMainViewport()->Pos;
ImGuizmo::SetRect(origin.x, origin.y, io.DisplaySize.x, io.DisplaySize.y);
ImGuizmo::Manipulate(fview, fproj, ImGuizmo::TRANSLATE, ImGuizmo::LOCAL, gizmat, nil, nil);

gGizmoHovered = ImGuizmo::IsOver();
Expand Down
13 changes: 12 additions & 1 deletion tools/euryopa/camera.cpp
Original file line number Diff line number Diff line change
@@ -1,10 +1,20 @@
#include "euryopa.h"
#include <cmath>

#define PI 3.14159265359f
#ifndef min
#define min(a, b) (a < b ? a : b)
#endif

float
ClampCameraFov(float fov)
{
if(!std::isfinite(fov))
return CAMERA_FOV_DEFAULT;
return fov < CAMERA_FOV_MIN ? CAMERA_FOV_MIN :
fov > CAMERA_FOV_MAX ? CAMERA_FOV_MAX : fov;
}

CCamera TheCamera;

using rw::Quat;
Expand Down Expand Up @@ -147,6 +157,7 @@ CCamera::DrawTarget(void)
void
CCamera::update(void)
{
m_fov = ClampCameraFov(m_fov);
if(m_rwcam){
m_rwcam->setFOV(m_fov, m_aspectRatio);
m_rwcam_viewer->setFOV(m_fov, m_aspectRatio);
Expand Down Expand Up @@ -292,7 +303,7 @@ CCamera::CCamera()

m_up.set(0.0f, 0.0f, 1.0f);
m_localup = m_up;
m_fov = 70.0f;
m_fov = CAMERA_FOV_DEFAULT;
m_aspectRatio = 1.0f;
m_rwcam = nil;
m_LODmult = 1.0f;
Expand Down
6 changes: 6 additions & 0 deletions tools/euryopa/camera.h
Original file line number Diff line number Diff line change
@@ -1,3 +1,9 @@
// Keep wheel zoom, manual input and saved cameras within the same FOV range.
constexpr float CAMERA_FOV_MIN = 1.0f;
constexpr float CAMERA_FOV_MAX = 90.0f;
constexpr float CAMERA_FOV_DEFAULT = 70.0f;
float ClampCameraFov(float fov);

class CCamera
{
public:
Expand Down
21 changes: 12 additions & 9 deletions tools/euryopa/euryopa.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1969,9 +1969,9 @@ handleRectSelect(void)
ctx.count = 0;

// Draw selection rectangle overlay
ImDrawList *dl = ImGui::GetForegroundDrawList();
ImVec2 p0(ctx.x1, ctx.y1);
ImVec2 p1(ctx.x2, ctx.y2);
ImDrawList *dl = EditorForegroundDrawList();
ImVec2 p0 = EditorUiPoint(ctx.x1, ctx.y1);
ImVec2 p1 = EditorUiPoint(ctx.x2, ctx.y2);
dl->AddRectFilled(p0, p1, IM_COL32(100, 150, 255, 40));
dl->AddRect(p0, p1, IM_COL32(100, 150, 255, 200), 0.0f, 0, 1.5f);

Expand Down Expand Up @@ -2122,7 +2122,7 @@ handleTool(void)
// Alt + short middle click resets wheel zoom while preserving plain
// middle-click selection and middle-button drag camera controls.
if(CPad::IsAltDown() && !CPad::IsCtrlDown()){
TheCamera.m_fov = 70.0f;
TheCamera.m_fov = CAMERA_FOV_DEFAULT;
Toast(TOAST_SELECTION, "FOV reset to 70°");
return;
}else if(!IsIplMapDocumentOpen() && CPad::IsCtrlDown()){
Expand Down Expand Up @@ -2355,7 +2355,8 @@ dogizmo(void)
float *fobj = (float*)&gizobj;

ImGuiIO &io = ImGui::GetIO();
ImGuizmo::SetRect(0, 0, io.DisplaySize.x, io.DisplaySize.y);
ImVec2 origin = ImGui::GetMainViewport()->Pos;
ImGuizmo::SetRect(origin.x, origin.y, io.DisplaySize.x, io.DisplaySize.y);

float snapValues[3];
float *snapPtr = nil;
Expand Down Expand Up @@ -2417,7 +2418,8 @@ dogizmo(void)
fobj = (float*)&gizobj;

ImGuiIO &io = ImGui::GetIO();
ImGuizmo::SetRect(0, 0, io.DisplaySize.x, io.DisplaySize.y);
ImVec2 origin = ImGui::GetMainViewport()->Pos;
ImGuizmo::SetRect(origin.x, origin.y, io.DisplaySize.x, io.DisplaySize.y);

ImGuizmo::OPERATION op = gGizmoMode == GIZMO_ROTATE ? ImGuizmo::ROTATE : ImGuizmo::TRANSLATE;
float snapValues[3];
Expand Down Expand Up @@ -2662,9 +2664,7 @@ Draw(void)
{
ImGuiIO &io = ImGui::GetIO();
if(!io.WantCaptureMouse && io.MouseWheel != 0.0f){
TheCamera.m_fov -= io.MouseWheel * gFovWheelStep;
if(TheCamera.m_fov < 1.0f) TheCamera.m_fov = 1.0f;
if(TheCamera.m_fov > 150.0f) TheCamera.m_fov = 150.0f;
TheCamera.m_fov = ClampCameraFov(TheCamera.m_fov - io.MouseWheel * gFovWheelStep);
}
}

Expand Down Expand Up @@ -2784,6 +2784,9 @@ Draw(void)

Scene.camera->endUpdate();
Scene.camera->showRaster(rw::Raster::FLIPWAITVSYNCH);
#if defined(_WIN32) && defined(RW_D3D9)
RenderDetachedEditorWindows();
#endif
frameCounter++;
}

Expand Down
26 changes: 26 additions & 0 deletions tools/euryopa/euryopa.h
Original file line number Diff line number Diff line change
Expand Up @@ -1240,3 +1240,29 @@ namespace Clouds

void gui(void);
void uiShowCdImages(void);

// UI coordinates are desktop-relative with multi-viewports, client-relative otherwise.
inline ImVec2 EditorUiPoint(float x, float y)
{
ImVec2 origin = ImGui::GetMainViewport()->Pos;
return ImVec2(origin.x + x, origin.y + y);
}
inline ImDrawList *EditorForegroundDrawList(void)
{
#ifdef IMGUI_HAS_VIEWPORT
return ImGui::GetForegroundDrawList(ImGui::GetMainViewport());
#else
return ImGui::GetForegroundDrawList();
#endif
}
inline void KeepNextEditorOverlayOnMainWindow(void)
{
#ifdef IMGUI_HAS_VIEWPORT
ImGui::SetNextWindowViewport(ImGui::GetMainViewport()->ID);
#endif
}
#if defined(_WIN32) && defined(RW_D3D9)
void RenderDetachedEditorWindows(void);
void InitializeEditorWindowDpi(void);
void BringEditorPanelsHome(void);
#endif
Loading
Loading