I've found the four places in the code section of the EXE where the size of the plot indicators ("bubbles") is hardcoded. Those values aren't unreasonable, the real problem is that the EXE increases them based on the screen height. I've located some code in that vein in the debugger, but I'm not at all sure that that's really it. (Also not sure if the width doesn't also have some impact.) But we can just decrease the base values to compensate for the adjustment.
For a static approach, one can use a hex editor [edit #3: see instructions in this post] and simply replace all occurrences of the floating-point numbers 42 and 68 (FP32 encoding) in Civ4BeyondSword.exe with a smaller number. The 68 is for the bubble shown when the selected unit is off-screen. Well, this is not totally simple because one needs to get the encoding right. [Edit #2: Moreover, there are actually four occurrences of 42 in the EXE and seven occurrences of 68. Only the first three of the former and the first one of the latter ought to be replaced as far as I know.] I can imagine a little tool that let's the user choose the size and perhaps also offers replacing GameSpy with Zulan's server – but I don't imagine anyone actually implementing that.
What I've implemented, tentatively, is a mod component that overwrites the offending values at runtime in the main memory and that could be merged into other mods with little effort (beyond recompiling the DLL). Here's the mod component with its source code:
https://github.com/f1rpo/Civ4_SMC_PoC (download)
The name is short for "self-modifying code - proof of concept" – I've written a little bit of a framework.
After unzipping, the mod folder should be renamed to match the name of the INI file inside. Caveat: The DLL has assertions enabled; hopefully none will fail, but, if they do, one may have to Alt+Tab out of fullscreen mode to unfreeze the game. Edit #1: And when using 1024x768 resolution, the mod will have almost no effect.
Works nicely on my end (screenshot; original size is at the bottom), and, for my AdvCiv mod, I've already implemented options on the BUG menu for either canceling out the height adjustment or setting a particular size or adjusting to the field-of-view value. (Edit #7: Now also implemented in a fork of BULL.) I've only been able to test this on Win 8.1 and Win XP and only with my Complete Edition (CE) from DVD. The virtual memory layout of the EXE should not depend on the OS and hardware, but the OS could still matter because the mod needs to temporarily lift write protections on a few pages of the code segment. This behavior might also cause trouble with virus scanners. Letting VirusTotal.com scan my DLL has not resulted in any detections; however, there could possibly also be detections at runtime based on memory accesses. Another concern are localized versions of the game. I don't know if those use the exact same build of the EXE as the CE (not really sure about the Steam "beta" and GoG version either). I suppose the differences in the memory layout can't be that great. My code already performs a sanity test, and, if that fails, will search for a particular sequence of binary instructions to determine an address offset that aligns the relevant part of the present EXE with the CE EXE. Edit #4: This thread makes me hopeful that localized editions don't actually use a different build of the EXE. Edit #5: Also heard back from a Linux user who didn't seem to have trouble. Edit #6: Tried Zulan's alternative EXE; no problem (only makes changes in the data segment, which doesn't affect code addresses).
So – do let me know if you encounter or foresee problems or if you have a better idea how to go about this.
Edit #1: This view shows the DLL changes relevant for merging this mod pretty well.
Edit #7: Removed mention of the large-address awareness (LAA) patch from this post - I've come to realize that the official BtS 3.19 EXE is already LAA, so this should not be a concern.
For a static approach, one can use a hex editor [edit #3: see instructions in this post] and simply replace all occurrences of the floating-point numbers 42 and 68 (FP32 encoding) in Civ4BeyondSword.exe with a smaller number. The 68 is for the bubble shown when the selected unit is off-screen. Well, this is not totally simple because one needs to get the encoding right. [Edit #2: Moreover, there are actually four occurrences of 42 in the EXE and seven occurrences of 68. Only the first three of the former and the first one of the latter ought to be replaced as far as I know.] I can imagine a little tool that let's the user choose the size and perhaps also offers replacing GameSpy with Zulan's server – but I don't imagine anyone actually implementing that.
What I've implemented, tentatively, is a mod component that overwrites the offending values at runtime in the main memory and that could be merged into other mods with little effort (beyond recompiling the DLL). Here's the mod component with its source code:
https://github.com/f1rpo/Civ4_SMC_PoC (download)
The name is short for "self-modifying code - proof of concept" – I've written a little bit of a framework.
After unzipping, the mod folder should be renamed to match the name of the INI file inside. Caveat: The DLL has assertions enabled; hopefully none will fail, but, if they do, one may have to Alt+Tab out of fullscreen mode to unfreeze the game. Edit #1: And when using 1024x768 resolution, the mod will have almost no effect.
Works nicely on my end (screenshot; original size is at the bottom), and, for my AdvCiv mod, I've already implemented options on the BUG menu for either canceling out the height adjustment or setting a particular size or adjusting to the field-of-view value. (Edit #7: Now also implemented in a fork of BULL.) I've only been able to test this on Win 8.1 and Win XP and only with my Complete Edition (CE) from DVD. The virtual memory layout of the EXE should not depend on the OS and hardware, but the OS could still matter because the mod needs to temporarily lift write protections on a few pages of the code segment. This behavior might also cause trouble with virus scanners. Letting VirusTotal.com scan my DLL has not resulted in any detections; however, there could possibly also be detections at runtime based on memory accesses. Another concern are localized versions of the game. I don't know if those use the exact same build of the EXE as the CE (not really sure about the Steam "beta" and GoG version either). I suppose the differences in the memory layout can't be that great. My code already performs a sanity test, and, if that fails, will search for a particular sequence of binary instructions to determine an address offset that aligns the relevant part of the present EXE with the CE EXE. Edit #4: This thread makes me hopeful that localized editions don't actually use a different build of the EXE. Edit #5: Also heard back from a Linux user who didn't seem to have trouble. Edit #6: Tried Zulan's alternative EXE; no problem (only makes changes in the data segment, which doesn't affect code addresses).
So – do let me know if you encounter or foresee problems or if you have a better idea how to go about this.
Edit #1: This view shows the DLL changes relevant for merging this mod pretty well.
Edit #7: Removed mention of the large-address awareness (LAA) patch from this post - I've come to realize that the official BtS 3.19 EXE is already LAA, so this should not be a concern.
Last edited: