Commit Graph
8 Commits
Author SHA1 Message Date
Marco Antonio J. Costaandmajcosta bbfd88c414 update mingw toolchain file while we're at it
still does not compile, it'll require its own set of changes to make
the code gcc-compliant
2026-07-23 19:29:55 -03:00
Marco Antonio J. Costaandmajcosta 5fd1d5f567 build with clang-cl from a toolchain file and a preset
The tree compiles and links under clang-cl, so make that a configuration
anyone can ask for rather than a command line to reconstruct:

  MSVC_DIRECTORY=/path/to/msvc cmake --preset '1dot13 Release clang-cl'

It is a check on the source, not a port -- MSVC still builds what ships. What
it buys is a second front end over every translation unit, which is how the
inline assembly with no operand size and the resource string with a raw 0xA9
were found, and it runs natively: clang-cl, lld-link, llvm-rc and llvm-lib
need no Wine, so a full JA2.exe takes a fraction of the time.

The toolchain file names every MSVC and SDK include directory, because
clang-cl does not read INCLUDE and LIB the way cl does, and picks the newest
version of each tree rather than pinning one. MSVC_DIRECTORY says where they
live and is reported plainly when it is missing or wrong.

build a bindable Bink import library when not building with MSVC

The shipped binkw32.lib is an old ordinal-based long-format import library.
MSVC's link.exe binds it, but clang-cl's lld-link does not: it leaves every
Bink import unresolved, so at run time the calls jump into arbitrary code and
crash the game at startup, six access violations deep in unrelated code before
the game's own handler gives up.

Rebuild the import library from binkw32.def with llvm-dlltool on any front end
other than MSVC. The library imports by ordinal, for the reasons binkw32.def
records: binkw32.dll exports decorated stdcall names that keep their leading
underscore (_BinkOpen@8), and llvm-dlltool strips that underscore from the
imported name whatever --no-leading-underscore says, so a by-name import would
look up a name the DLL does not export and Wine would substitute a builtin stub
that aborts ("unimplemented function binkw32.dll.BinkSetSoundSystem@8").
Ordinals have no such ambiguity and match the retail DLL. MSVC keeps binding the
shipped library, so the retail build is untouched.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>

refactor toolchain

make the preset template something CMake will read

The template carries two // comments. JSON has no comments and neither does
the preset format, so CMake refuses the whole file:

  CMakePresets.json:10: Missing '}' or object member name

Which means the file CopyUserPresetTemplate drops into the source directory
has never worked as handed over -- "cmake --preset '1dot13 Release'" fails
until you delete the comments yourself.

The text they carried is worth keeping, so it moves to the description field
the format does have, and cmake --preset '1dot13 Release' now configures.
2026-07-23 19:29:55 -03:00
fd2c74727e Make LANGUAGE switchable in runtime (#653)
squashed into a single commit because doing it in steps that all
compiled involved a lot of boilerplate that is pointless to commit to
the repository. GH still has the PR for reference.

g_lang, MAX_MESSAGES_ON_MAP_BOTTOM, and GetLanguagePrefix() were
compile-time constants selected by the ENGLISH/GERMAN/... build
define. They're now runtime, defaulting to the same per-exe value the
define used to pick, and overridable at startup from [Ja2 Settings]
LANGUAGE in Ja2.ini.

-

XMLTacticalMessages is filled at runtime from NewTacticalMessages.xml,
never from compiled-in per-language data: all 8 per-language definitions
were the identical all-zero { L"" }. Delete them and define one shared
buffer in Utils/XML_Language.cpp (the loader) instead of pointer-rebinding
it like the static tables — this drops 9 dead 800KB zero-buffers (8
namespaced copies in LanguageStrings.cpp plus the standalone one) and
leaves no bind-ordering hazard for the XML load path.

-

ExportStrings.cpp privately recompiled one language's full text table
by #including the raw _<LANG>Text.cpp inside namespace Loc, keyed off
the exe-level ENGLISH/GERMAN/... compile macro (whichever the build
happened to select). That's redundant with the pointer globals every
other subsystem already uses (Text.h / LanguageStrings.cpp).

Drop the private copy; the unqualified table names in Loc::ExportStrings
now resolve to the global pointer externs, which BindLanguageStrings has
already rebound to the runtime g_lang by the time this runs (EXPORT_STRINGS
ini flag, checked after GetRuntimeSettings in sgp.cpp). gs_Lang (used only
by Loc::Translate for the Polish/Russian byte remap on raw .edt exports) is
now derived from g_lang via ToLocLanguage, so the export always matches
whatever language is actually active instead of a compile-time pick.

-

Editor/popupmenu.cpp and Strategic/Scheduling.cpp kept their own
call-site extern of gszScheduleActions as CHAR16[NUM_SCHEDULE_ACTIONS][20]
after the real definition changed into a rebindable pointer
(CHAR16 (*)[20], LanguageStrings.cpp). MSVC decays the outer array
dimension when mangling globals, so both declarations produce the same
symbol (?gszScheduleActions@@3PAY0BE@_WA) and the mismatch linked
silently -- but the array-typed TUs then indexed the 4-byte pointer
slot itself as string data, so the editor schedule popup and the map
schedule message text read garbage.

-

add text.def to be single-source of truth on symbol names and use it
 .much simpler, less error prone if adding more strings

-

add pseudo interface for language state. MAX_SAGES_ON_BOTTOM must always
 change in lockstep with g_lang. this isn't foolproof but better

---------

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
Co-authored-by: Claude Sonnet 4.5 <noreply@anthropic.com>
2026-07-21 05:33:03 -03:00
Marco Antonio J. Costaandmajcosta 1d58bda82d cross-compilation scaffolding WIP
requires clang/lld or mingw, obviously

just make sure the MSVC_DIRECTORY env variable points to valid Visual Studio Build Tools directory
and do: `cmake -S . -B build -DCMAKE_TOOLCHAIN_FILE=clang_or_mingw_toolchain_file`
2024-12-13 19:24:59 -03:00
Marco Antonio Jaguaribe Costaandmajcosta 98cdffe5fd (actually) fix broken MS2022 behavior
a recent Visual Studio update introduced an error unless there is a
CMakePresets.json file present, completely blowing up the previous
setup.

after this commit, you should either delete the CMakeUserPresets.json
file from your root or add it to your system - NOT repo! - excludesFile:
https://stackoverflow.com/questions/7335420/global-git-ignore
2024-12-09 14:19:25 -03:00
57d2674f37 Use a modifiable user-preset sample for VS 2022/2019 (#97)
* Use a modifiable user-preset sample for VS 2022/2019

Customizing a repo-tracked preset file doesn't work:

Type in your gamedir for debugging, or toggle verbose mode for the build, or configure Chinese
UB MapEditor: you now have an unstaged `CMakePresets.json` change in your working directory.
very annoying.

Also, Visual Studio 2022's preset support has a bug: if you have a `CMakePresets.json` file,
no matter in which file (user or repo) the preset you have selected is defined, if you click
"Manage Configurations..." it will always open `CMakePresets.json` for editing, setting the
user up for failure and editing the commited-to-repository file.

Having just the `CMakeUserPresets.json` file also sidesteps another poor Visual Studio 2022
decision: hiding in Folder View files that are .gitignore'd (like `CMakeUserPresets.json`).

In the absence of a `CMakePresets.json` file, selecting "Manage Configurations..." will open
the right file for editing.

The workflow is then:

Copy `CMakeUserPresets.json.sample` into `CMakeUserPresets.json` _once_, then customize
that to your heart's content without git bothering you and accidentally adding an
unwanted change to a patch. Or make your own.

* Added auto-copy of profile template.

* declutter things a bit

move function out of root cmakelists.txt file
move user preset template to a presets directory

this is horrible and I hate it

Co-authored-by: CptMoore <39010654+CptMoore@users.noreply.github.com>
2023-01-21 20:26:49 -03:00
majcostaandGitHub e4295acfec simplify the language/executable validation function (#79)
* simplify the language/executable validation function

removing the 'ALL' corner-case so that the default behavior is to configure all valid languages and applications allows to simplify this function quite a bit

* keep the CMakePreset.json options listed for ease of use
2023-01-17 23:32:38 -08:00
Marco Antonio Jaguaribe Costa 8609944467 Add a CMake build
Tried to stay as close as possible to ja2_2019.sln

On Visual Studio 2022 just Project -> CMake Settings for Ja2, add
the x86 configurations you want and press F7.

Below shows how the -DLanguages -DApplications switches work, If you don't
set them, the CMakeCache.txt of them will be set to ENGLISH and JA2,
respectively:

cmake [...] // nothing set, configure just JA2_ENGLISH.exe by default
cmake [...] -DApplications="JA2UB" // configures just Unfinished Business
cmake [...] build -DApplications="JA2UB;JA2UBMAPEDITOR" // Unfinished Business and UB Map Editor
cmake [...] build -DApplications="JA2UB;JA2MAPEDITOR;ALL" // ALL is in the list, configures every application
cmake [...] build -DApplications="JA2MAPEDITOR;DeathStranding" // fatal error: DeathStranding not an application

cmake [...] -DLanguages="GERMAN" // configures just German targets
cmake [...] build -DLanguages="GERMAN;ENGLISH" // German and English
cmake [...] build -DLanguages="GERMAN;ENGLISH;ALL" // ALL is in the list, configures every language
cmake [...] build -DLanguages="ENGLISH;ESPERANTO" // fatal error: ESPERANTO not supported
2023-01-14 02:08:39 -03:00