henricj/dunelegacy

INFO : SCENO001.INI:30: Invalid or occupied position for 'Soldier': '9' (-7x-16/9) after parsing Harkonnen,Soldier,256,9,64,Hunt!

Opened this issue · 1 comments

juj commented

Ordos campaign mission 1 has the following .INI description:

[BASIC]
LosePicture=LOSTBILD.WSA
WinPicture=WIN1.WSA
BriefPicture=HARVEST.WSA
TimeOut=0
MapScale=1
CursorPos=2333
TacticalPos=2071
LoseFlags=4
WinFlags=6

[MAP]
Seed=1498

[Harkonnen]
Quota=0
Credits=0
Brain=CPU
MaxUnit=25

[Ordos]
Quota=1000
Credits=1000
Brain=Human
MaxUnit=25

[UNITS]
ID038=Harkonnen,Soldier,256,9,64,Hunt
ID037=Harkonnen,Soldier,256,1388,64,Hunt
ID036=Harkonnen,Trooper,199,1488,64,Ambush
ID035=Harkonnen,Trooper,199,1633,64,Ambush
ID034=Harkonnen,Trooper,142,1878,64,Ambush
ID033=Harkonnen,Soldier,256,1953,64,Ambush
ID032=Harkonnen,Trooper,199,2090,64,Ambush
ID031=Ordos,Soldier,256,2209,32,Guard
ID030=Ordos,Raider Trike,256,2207,64,Guard
ID029=Ordos,Soldier,256,2267,64,Guard
ID028=Ordos,Soldier,256,2394,224,Guard
ID027=Harkonnen,Soldier,256,2389,64,Ambush
ID026=Ordos,Raider Trike,256,2460,64,Guard
ID025=Harkonnen,Soldier,256,2534,64,Ambush
ID024=Harkonnen,Soldier,256,2851,64,Ambush
ID023=Harkonnen,Trooper,85,2839,64,Ambush
ID022=Harkonnen,Soldier,256,3261,64,Hunt

[STRUCTURES]
ID000=Ordos,Const Yard,256,2333

When that level is loaded, it will print the following warnings to log:

INFO    :   SCENO001.INI:30: Invalid or occupied position for 'Soldier': '9' (-7x-16/9) after parsing Harkonnen,Soldier,256,9,64,Hunt!
INFO    :   SCENO001.INI:46: Invalid or occupied position for 'Soldier': '3261' (45x34/3261) after parsing Harkonnen,Soldier,256,3261,64,Hunt!

The first warning line here corresponds to line

ID038=Harkonnen,Soldier,256,9,64,Hunt

above.
Here pos equals 9, which seems to be a bit-packed XY coordinate, with X coordinate being the lower 6 bits, and Y coordinate being the rest of the upper bits, as parsed here:

[[nodiscard]] int getXPos(int pos) const {
return (version_ < 2 ? (pos & 0x3f) : (pos % logicalSizeX_)) - logicalOffsetX_;
}
[[nodiscard]] int getYPos(int pos) const {
return (version_ < 2 ? ((pos >> 6) & 0x3f) : (pos / logicalSizeX_)) - logicalOffsetY_;
}

So this unit has coordinates X: 9, Y: 0. However then there is this logicalOffsetX_ and logicalOffsetY_ that are subtracted from the XY coordinates. In this case this offset value is 16, resulting in final XY coordinates of X: -7, Y: -16, hence attempting to place the soldier out of the screen.

Not at all sure which part here would be the wrong computation.

Git pointed changes around this all the way back to 317a19d where this logic was last adjusted.

Based on that, I thought to try to change this code to

diff --git a/include/INIMap/INIMap.h b/include/INIMap/INIMap.h
index f2c5ebd0..5a7cffb1 100644
--- a/include/INIMap/INIMap.h
+++ b/include/INIMap/INIMap.h
@@ -85,10 +85,10 @@ protected:
     void checkFeatures() const;

     [[nodiscard]] int getXPos(int pos) const {
-        return (version_ < 2 ? (pos & 0x3f) : (pos % logicalSizeX_)) - logicalOffsetX_;
+        return (version_ < 2 ? (pos & 0x3f) : (pos % logicalSizeX_) - logicalOffsetX_);
     }
     [[nodiscard]] int getYPos(int pos) const {
-        return (version_ < 2 ? ((pos >> 6) & 0x3f) : (pos / logicalSizeX_)) - logicalOffsetY_;
+        return (version_ < 2 ? ((pos >> 6) & 0x3f) : (pos / logicalSizeX_) - logicalOffsetY_);
     }

     std::string mapname_;

thinking that maybe logicalOffsetX_ and logicalOffsetY_ should apply only when logicalSizeX_ is being used, but that clearly did not work and caused many more units to fall off the screen, and caused much more issues.

MapScale is equal to 1 on first Ordos level, which results in this block being active:

case 1: {
sizeX_ = 32;
sizeY_ = 32;
logicalOffsetX_ = 16;
logicalOffsetY_ = 16;
} break;

Nothing catches my eye here to figure what could be wrong. In addition to those two units not being possible to be placed in the level, it does look like something is off there also in the units that do get placed in the level, as hinted by this one enemy trooper being placed right at the very left edge of the screen, which felt like a bit odd placement:

image

juj commented

it does look like something is off there also in the units that do get placed in the level, as hinted by this one enemy trooper being placed right at the very left edge of the screen, which felt like a bit odd placement:

Hmm no, it does seem that the trooper is right there at the edge of the screen in original Dune 2 also:

image

That makes me wonder maybe the original game asset files did have quirks like this. (did the original game use these .INI based description files?)