Skip to content

Add native world-map zoom rendering backend - #6037

Draft
Huitzilopochtli-98 wants to merge 4 commits into
DFHack:developfrom
Huitzilopochtli-98:worldmap-zoom-render
Draft

Huitzilopochtli-98 wants to merge 4 commits into
DFHack:developfrom
Huitzilopochtli-98:worldmap-zoom-render

Conversation

@Huitzilopochtli-98

@Huitzilopochtli-98 Huitzilopochtli-98 commented Nov 5, 2026 •

Copy link
Copy Markdown

World Map Zoom enlarges the high-level embark Biome map and normal fortress world map at 2x/4x while preserving native text/control size. This PR contributes its native rendering service to DFHack so the backend can be built against each release's own structures and metadata.

Related to #6026. Adapted from the Zlib-licensed World Map Zoom project, retaining the original notices. The released mod has successful Windows in-game testing, including player validation.

Method and scope

The native map is drawn at its original coordinates into an SDL target texture. A cropped region is copied back beneath native-size interface drawing. Dirty-cell batches share the target pass; incomplete new crops receive one native full-map fallback. SDL state is saved/restored explicitly, and camera generations prevent stale crops from being composited.

The plugin documentation now explains the coordinate math, full/incremental rendering sequence, Direct3D motivation, inverse input mapping, thread ownership, and teardown. It includes a concrete centered-2x client sequence and explains the GUI client's responsibilities. The GUI/input helpers remain in the reference project; its released version guards need adaptation for development builds.

Revisions addressing the requested review

  • Make the canvas a self-contained header with explicit SDL-operation dependencies. Tests include it normally at the top and use official SDL types, rather than fake DF classes and includer globals.
  • Use named SDL pixel-format, target-access, blend, scaling, event, and renderer-capability constants. Split target creation, crop calculation, state saving, clearing, restoration, and composition into documented operations.
  • Publish camera/screen decisions from simulation/core-lock context. Renderer hooks consume that snapshot and display-side renderer/map-port fields; they do not inspect viewscreens or acquire the core lock.
  • Remove Windows.h and module pinning. New core-owned render-task handles support pending cancellation and report completion only after the callback and its captures are destroyed. Renderer cleanup removes hooks/event watches on their owning thread before unload is permitted.
  • Support ordinary command unload without a core lock, nonblocking Lua stop() plus later polling, and inline render-thread cleanup during process shutdown. A suspended synchronous unload or an incomplete cleanup refuses to unload the module.

The core task API, documentation, and independent lifetime tests are isolated in follow-up commit af4f46e, so that support can be reviewed or split out independently. Renderer refactoring/methodology and graphics tests are in f9b0d85. A third follow-up, 2fcb9c9, closes admission before idle unload and fences cleanup queued by stop() even when preparation never happened. Its native regression failed against the old binary and passes with the fix. These append to the reviewed history; no force-push was used.

Validation at 2fcb9c9

  • Windows CMake build/link of DFHack core, hook, renderer, and matching test-runtime plugins.
  • Both standalone CTests: canvas state/coverage/invalidation/error handling and core task cancellation, capture destruction, in-flight waits, and exception cleanup.
  • Actual native title-screen API suite: 30 checks in a separate DF 53.16 instance using the rebuilt runtime.
  • Native lifecycle checks: immediate prepare-then-stop; an unprepared-stop/unload regression; refusal of suspended-context unload; asynchronous stop; ordinary command unload; DLL disappearance from the process module list; reload after unload; and normal native process shutdown with a prepared renderer, exit code 0.
  • Production-canvas exact pixel comparisons at 2x and 4x on direct3d, direct3d11, direct3d12, opengl, opengles2, and software, including unchanged interface pixels. The optional SDL test uses native 1x output as its oracle because framebuffer colour encoding can differ from nominal RGB constants.
  • Sphinx HTML/text with warnings treated as errors, DFHack whitespace/authors/script-documentation checks, and applicable pinned pre-commit hooks.

The initial native build remains enabled on Windows; native Linux compilation/acceptance and full embark/fortress zoom-GUI retesting of the refactored integration remain outstanding. This stays a draft for maintainer review of the integration and core task API. Exact source/structure compatibility checks remain in place and are derived from the build rather than fixed to the standalone mod release.

@ab9rf ab9rf left a comment •

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In addition to the specific issues commented on above, this toolset needs documentation explaining its methodology - the code is virtually devoid of any commentary that explains why it's doing what it's doing. There's a lot of code here and basically no explanation of why it does what it does. AI slop is fine for personal tools, but I have to understand the code I'm being asked to commit to maintain, and if you make it too hard for me to do that, I'm not going to agree to that.

I am also uncomfortable with the way this interacts with the render thread and specifically the way the tool doesn't unload cleanly. I think it should be possible to arrange for a clean unload - suggest the author review our developer-facing documentation on how DF's main and simulation threads interact for more insight.

I also don't find the API documentation sufficient - I read through it twice and I still don't understand how I'm supposed to use it. Basically, I'm not seeing the general use case for this functionality.

Comment thread plugins/worldmap-zoom-canvas.h Outdated
std::lock_guard lock(state_mutex);
renderer_name = info.name ? info.name : "unknown";
}
texture = sdl.create_texture(sr, 0x16362004, 2, w, h); // ARGB8888 / TARGET

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

magic number

Comment thread plugins/worldmap-zoom-canvas.h Outdated
}
}
if (full || (!valid && started)) {
if (sdl.set_color(sr, 0, 0, 0, 255) != 0 || sdl.clear(sr) != 0 ||

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

i don't like this - while i understand what it's doing, it was considerable work to understand what it is, and thus it's telling an obscure story, and that's bad

Comment thread plugins/worldmap-zoom-canvas.test.cpp Outdated
}
} sdl;

#include "worldmap-zoom-canvas.h"

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

#includes should be at the top of the file unless there is a compelling reason for them to be somewhere else. please review our contribution standards.

Comment thread plugins/worldmap-zoom-render.cpp Outdated
#include "lauxlib.h"
#include "lua.h"

#define WIN32_LEAN_AND_MEAN

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

windows-specific code needs to be gated by an #ifdef and our contribution standards require avoiding including Windows.h whenever possible, thus this include requires a justification

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants