Jump to content

EXE editing & programming issues


MrFlibble

Recommended Posts

Btw, that game gamePause? variable... as far as i can tell, is never set to 1 in the game

which would seem to indicate its some type of debugging switch... i was actually wondering at one point if it was perhaps a map editor, but i cant seem to find any proof of that

Link to comment
Share on other sites

just found this, skips the intro completely, and the menu

takes you straight to the select a house screen (also skips the mentat/mission brief screens)

Arrakis: file address: 0x3B7C2

dseg:37A2 00 00            introMenuSkip  dw 0

Dynasty: File address: 0x3AD12

dseg:3212 00 00            introMenuSkip  dw 0 

Link to comment
Share on other sites

Game endings can be removed by noping here

seg023:03B0 9A 20 00 AE 42                    call    j_gameEndingPlay

Arrakis: 0x171E0

Dynasty: 0x171DF

This whole chunk is run after the final mission  (this occurs right before the check to see if we should do the copy protection)

seg023:0387 83 3E A6 38 09                    cmp    missionNumberPrevious, 9

seg023:038C 75 35                            jnz    short loc_225F3

seg023:038E 9A 31 01 71 39                    call    sub_39841

seg023:0393 B8 0F 00                          mov    ax, 0Fh

seg023:0396 50                                push    ax

seg023:0397 FF 36 2C 3C                      push    word_4704C

seg023:039B FF 36 2A 3C                      push    word_4704A

seg023:039F 9A 00 00 A3 33                    call    screenFadeOut

seg023:03A4 83 C4 06                          add    sp, 6

seg023:03A7 33 C0                            xor    ax, ax

seg023:03A9 50                                push    ax

seg023:03AA 9A 0E 00 DE 32                    call    sub_32DEE

seg023:03AF 59                                pop    cx

seg023:03B0 9A 20 00 AE 42                    call    j_gameEndingPlay

seg023:03B5 9A 20 00 03 43                    call    j_gameShutdown

seg023:03BA 33 C0                            xor    ax, ax

seg023:03BC 50                                push    ax              ; status

seg023:03BD 9A 77 03 00 10                    call    _exit

Link to comment
Share on other sites

Ooh, thanks one more time ;D I'll implement this as soon as I got time :)

BTW, regarding the demo/debug mode you discovered, I think it would be interesting to know if the Dune 2 Demo EXE could be modified the other way round - i.e. make it playable (if you haven't played it, the demo only shows a scripted battle between the Atreides and Harkonnens). I can't be sure, but it seems to me that the Demo EXE contains most of the code required to play the game - and it's a tad different from the final release. Anyhow, just some random thoughts :)

Link to comment
Share on other sites

i had a quick look on sunday, and im pretty sure you can play it.. a few variables i was playing with gave me that idea

one in particular when set to 2 would ignore the mouse movement (altho if changed during playback/game it had no effect), but it was set to 2 in the demo when it was playing

but, the house selection/briefing/menu code is all missing. and when i did get the mouse moving (with the playback stopped), i couldnt click on anything (there must be another variable somewhere.. unless the code to interpret clicking is missing altogether)

I could use the keyboard commands to change units tho, so it wasnt completely ignoring me

perhaps ill try get the demo script playing on the full version and work from there

Link to comment
Share on other sites

that might be of some help yeah

ive actually been working on an EMC decompiler/compiler the past few days.. think its done now

it can decompile build, unit and team.. and recompile them to an exact match of the script used to dump

currently im unaware of what all the functions called by unit and team do, so its currently using ida func names for alot of them ;)

but,

From [carryall]...  Check if the unit type we're holding is a harvester, if it is.. get the "HarvesterSpiceCapacity" variable

... atleast thats what i think this does :) its going to require alot more investigation

l1856:

Execute            GetHoldingType

Push                0

PushVal            16

Evaluate            Equal

IfNotGoto          l1901

Execute            CheckHarvestReturn

from [MCV]

l2257:

PushReg            0

PushVal            12

Evaluate            Equal

IfNotGoto          l2266

Execute            MCVDeploy

Link to comment
Share on other sites

Don't forget the Deviator only deviating units to the Ordos side instead of the side who owns the Deviator. :)

I'm not sure so sure this can be fixed, i have located a variable in the unit struct which when set will cause the unit to become ordos... i think this variable is set to the owner of the deviator unit, but in multiple places, you see this

seg006:0B2A C4 5E DE                          les    bx, [bp+unitGamePtr]

seg006:0B2D 26 80 7F 59 00                    cmp    es:[bx+_unitGame.HouseTemp], 0

seg006:0B32 74 05                            jz      short loc_16909

seg006:0B34 B8 02 00                          mov    ax, 2

one function in particular, which is named "UnitHouseIDGet"

seg031:363A                  loc_2B99A:                              ; CODE XREF: unitGameHouseIDGet+9j

seg031:363A C4 5E 06                          les    bx, [bp+unitGamePtr]

seg031:363D 26 80 7F 59 00                    cmp    es:[bx+_unitGame.HouseTemp], 0

seg031:3642 74 05                            jz      short returnHouseID

seg031:3644 B8 02 00                          mov    ax, 2          ; Ordos

seg031:3647 EB EF                            jmp    short Done_1

The top one, when changing it.. will affect the units color on the field.. wonder why they did it this way

Link to comment
Share on other sites

Nyerguds, found some info in the disassembly that might be of use to you and your editor

This is all based on memory accessing ive seen, i havnt actually tested anything as of yet.

First, as far as i can tell OptsFiTW is a WORD and begins at +36, not +37.. and the Enum reads as

(ive only added a value if a TEST against it exists, added all which ive found)

00000002 ; enum _unitOptsFitW (bitfield)

00000002 _unitOptsFitW_2  = 2

00000004 _unitOptsFitw_4  = 4

00000008 _unitOptsFitW_8  = 8

00000010 _unitOptsFitW_10  = 10h

00000020 _unitOptsFitW_20  = 20h

00000040 _unitOptsFitW_40  = 40h

00000080 _unitOptsFitW_80  = 80h

00000400 _unitOptsFitW_400  = 400h

00000800 _unitOptsFitW_800  = 800h

00008000 _unitOptsFitW_8000  = 8000h

and OptsWocaTuro is also a WORD, but you have it at the correct offset

00000001 ; enum _UnitOptsWocaTuro (bitfield)

00000001 _UnitOptsWocaTuro_1  = 1

00000002 _UnitOptsWocaTuro_2  = 2

00000020 _UnitOptsWocaTuro_20  = 20h

00000040 _UnitOptsWocaTuro_40  = 40h

00000100 _UnitOptsWocaTuro_100  = 100h

00000200 _UnitOptsWocaTuro_200  = 200h

00000800 _UnitOptsWocaTuro_800  = 800h

00001000 _UnitOptsWocaTuro_1000  = 1000h

00002000 _UnitOptsWocaTuro_2000  = 2000h

Link to comment
Share on other sites

I won't count on that to tell me which bits are used... In C&C1 it frequently does bitshifting on the value to get to the other bits. It's hard to trace.

Also, it makes little difference to the editor that they're 2 bytes. To keep the options visible for editing I want to split them up as much as possible, so single bytes are better for that. Even if the game handles 2 of them together, they're still bit switches anyway, so it hardly matters.

Ideally I'd want to spread every bit to a separate option line in the editor, but I can't implement that anymore at this point, since it wasn't designed for it. As it is, every entry in the editor needs to have a byte size > 0, so I can't add 8 entries for one single byte.

Link to comment
Share on other sites

Heya guys;

I was wondering if there was a possible way that we could add in-game text messages triggered by events or time variables. It could really enhance the storytelling, which is very important for a dune game. This sounds possible as there is the option for in-game messages, like when you select a building for the first time they show up and tell something. And there is that message that tells there is not enough concrete space.

I also would like to remove the option that when you are out of harvesters, the game brings one for you. Or at least making it a very late delivery could be wonderfull.

I believe both these aspects are buried in exe right?

Also, there are crew values for vehicles in the manual. Sometimes when your harvester gets destroyed, a single soldier is given. And when buildings blow up, they leave back random number and hp of soldiers. These could be used to create interesting options. Does anyone have any idea on them? Feels like the more number of crew for a vehicle, the more possibility of a survivor soldier emerging from its ruins. I will check nyerguds editor and try to figure out.

Buildings slowly degenerate when without power right? They also degenerate faster when built on bare rock. So there is a kind of degeneration value somewhere. and when you repair a building it regenerates so there is some code about it too. Repair facility repairs vehicles too. Can we somehow make regenerating units or units with a limited lifespan?

Spice bloom is also interesting. Does anybode know where are the codes for it and what could possibly be done with it? Maybe we can use it like crates of red alert and similar? -Manual has hints for this. It says it may contain an abandoned vehicle or credits or spice, and if you shoot, you destroy if there was a "prize" and if you walk over you lose your unit if its spice. In the game, there is only spice.

Does anyone have any idea to solve the half damage in some directions bug? This is also interesting; how does the game decide to deal half damage? How can we use this?

Link to comment
Share on other sites

I was wondering if there was a possible way that we could add in-game text messages triggered by events or time variables. It could really enhance the storytelling, which is very important for a dune game. This sounds possible as there is the option for in-game messages, like when you select a building for the first time they show up and tell something. And there is that message that tells there is not enough concrete space.

segra or Nyerguds may prove me wrong, but somehow I don't think this is possible...

Link to comment
Share on other sites

While it could be done, the amount of work would be substantial... if there is even enough room in the exe, what makes it hard is the use of OVERLAYS. Everytime the game starts, different segments start at different locations... it makes debugging a real pain.

But in the long run, you would be better off rewriting the game :)  Hint Hint someone? ;)

Ive seen the harvester code somewhere, cant remember exactly where.. but u could disable it

Bloom seems to be loaded into the map pieces array somewhere, this map array uses a bit field which one of the bits is for determining if FOG is still covering it or not

Link to comment
Share on other sites

oh also, in the mission ini loading function... theres a section it attempts to load called SPECIAL

I tested this out, and the result is interesting :)

in the [MAP] section of a mission ini,

I added...

Special=2407

a "Bloom" appeared at 2407, which looked slightly different to the spice bloom. When walking on it, an Orni-Thopter appeared and took off

Link to comment
Share on other sites

Harvesters are checked by this function, to quickly sum it... it returns 1 if it finds a harvester, 0 if it doesnt.

it checks all the buildings, except for heavy factorys, then checks the carry alls,

then checks all ground units

if all come up empty, it checks for a refinery if one exists it creates a harvester, returning 1

otherwise, it returns 0

; int __fastcall far unitGameHarvesterFind(int,int,int,int houseID)

seg031:21E7                  unitGameHarvesterFind proc far          ; CODE XREF: sub_2191E+59FP

seg031:21E7                                                          ; sub_2216C+AP

seg031:21E7

seg031:21E7                  buildingGamePtr = dword ptr -0Ch

seg031:21E7                  unitGamePtrCarryAll= dword ptr -8

seg031:21E7                  unitGamePtr    = dword ptr -4

seg031:21E7                  houseID        = word ptr  6

seg031:21E7                  arg_6          = word ptr  0Ch

seg031:21E7

seg031:21E7 55                                push    bp

seg031:21E8 8B EC                            mov    bp, sp

seg031:21EA 83 EC 0C                          sub    sp, 0Ch

seg031:21ED 56                                push    si              ; int

seg031:21EE 8B 76 06                          mov    si, [bp+houseID]

.....

.....

seg031:22CA 9A FD 00 8B 1E                    call    buildingGameFind

seg031:22CF 83 C4 08                          add    sp, 8

seg031:22D2 89 56 F6                          mov    word ptr [bp+buildingGamePtr+2], dx

seg031:22D5 89 46 F4                          mov    word ptr [bp+buildingGamePtr], ax

seg031:22D8 0B C2                            or      ax, dx

seg031:22DA 74 4D                            jz      short RefineryNotFound

Modify this JZ to a JMP and it should never create a harvester again...

who knows what doing this may do to the game tho :)

Link to comment
Share on other sites

omg, cool... I stumbled upon the unit-spawning blooms before when messing around with the exe, but these only gave Ordos troopers then.

As for that function... is that the one for replacing a harvester, for bringing the original harvester to the refinery after building one, or both?

Link to comment
Share on other sites

All it does is check if a harvester is available, anywhere (in a building, or a carryall, or just on the field)... if not, it creates one, if a refinery exists

aside from that it just returns 1 if it finds a harvester.. it seems to be called quite regularly.

not sure what else its used for

Link to comment
Share on other sites

oh, I see.

Well, I remember the buildings ecm script containing code to automatically bring in a harvester. This is probably used for the harvest replacements you get in the first missions, and for the AI's harvester replacing.

Link to comment
Share on other sites

oh also, in the mission ini loading function... theres a section it attempts to load called SPECIAL

I tested this out, and the result is interesting :)

in the [MAP] section of a mission ini,

I added...

Special=2407

a "Bloom" appeared at 2407, which looked slightly different to the spice bloom. When walking on it, an Orni-Thopter appeared and took off

Wow, that's a really cool find ;D

"gameEndingPlay" function

ovr185:0000 55                             push    bp

...

...

ovr185:0019 A1 2C 3A                       mov     ax, gameHumanTeamID

ovr185:001C 0B C0                          or      ax, ax

ovr185:001E 74 0C                          jz      short endHark

ovr185:0020 3D 01 00                       cmp     ax, 1

ovr185:0023 74 67                          jz      short endAtre

ovr185:0025 3D 02 00                       cmp     ax, 2

ovr185:0028 74 3D                          jz      short endOrdos

ovr185:002A EB 60                          jmp     short endAtre          <<<< If the teamID doesnt match 0,1,2... use Atreides

segra, could you please tell how to make the Harkonnen ending play for the Sardaukar? I have successfully changed the other two endings to the Fremen and the Mercenaries (3D 03 00 74 67 3D 05 00 74 3D), but I don't get it how to change the Harkonnen to Sardaukar and why it is different in the first place...

Another thing, I have played with the skip ending segment you have pointed me to, but it skips both the ending cutscene and the credits (the game ends right after the score screen). Is it possible to skip the cutscene only, and leave the ending credits?

Link to comment
Share on other sites

segra, could you please tell how to make the Harkonnen ending play for the Sardaukar? I have successfully changed the other two endings to the Fremen and the Mercenaries (3D 03 00 74 67 3D 05 00 74 3D), but I don't get it how to change the Harkonnen to Sardaukar and why it is different in the first place...

ovr185:001C 0B C0                            or      ax, ax

ovr185:001E 74 0C                            jz      short endHark

as Harkonnen is 0, the result of the OR is zero but Sardaukar is 4. you could just NOP the final jump

ovr185:0028 74 3D                          jz      short endOrdos

ovr185:002A EB 60                          jmp    short endAtre

change the EB60 to 9090. Probably the easiest approach.

Yeah you can stop the movie playing, altho theres no actual skip for it. NOPing over this works just fine

ovr185:0056 9A 2A 00 F0 42                    call    j_MoviePlayer

Arrakis: 0x46866

Dynasty: 0x45A06

Link to comment
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...

Important Information

We have placed cookies on your device to help make this website better. You can adjust your cookie settings, otherwise we'll assume you're okay to continue.