MrFlibble Posted December 18, 2009 Author Share Posted December 18, 2009 And as for "repair hold".... I wonder if this can't be achieved by some sort of scripting in an EMC file or something (if I'm not mistaken that's how the "always return to repaired units to previous position on the map" and the "turret increased range" thingies were solved).BUILD.EMC has nothing to do with the sidebar command interface, and cannot be edited so that a button will be added to the Repair Facility that will allow to pause unit repair process. The sidebar commands are partially controlled via the regular parameters accessible via Nyerguds' editor, others seem to be hardcoded elsewhere. Quote Link to comment Share on other sites More sharing options...
MrFlibble Posted February 2, 2010 Author Share Posted February 2, 2010 I wonder what the code for skipping the Barracks prerequisite for the Harkonnen WOR looks like. It's probably the only code exception of this type, as no other tech tree differences involve skipping a building IIRC. Quote Link to comment Share on other sites More sharing options...
Nyerguds Posted February 3, 2010 Share Posted February 3, 2010 Probably a bit mask. Something that checks if the house is Harkonnen and the building ID the WOR, then takes the existing prerequisites bit mask it should check, and then does "AND [value], FBFFh" on it, to remove the Barracks bit from it.(FBFFh = 1111 1011 | 1111 1111, so it allows all bits to go through except for the 0400h bit)[edit]Found it ;DIt was even already documented in Segra's database:seg010:1C28 01E cmp si, 7 ; if WOR Factoryseg010:1C2B 01E jnz short notWOR ; Jump if Not Zero (ZF=0)seg010:1C2D 01E les bx, [bp+buildingGamePtr] ; Load Full Pointer to ES:xxseg010:1C30seg010:1C30 loc_1C060: ; if harkonnenseg010:1C30 01E cmp es:[bx+_buildingGame.houseID], 0seg010:1C35seg010:1C35 loc_1C065: ; Jump if Not Zero (ZF=0)seg010:1C35 01E jnz short notWORseg010:1C37 01E cmp missionNumberPrevious, 1 ; if missionnumberprevious >= 1seg010:1C3C 01E jl short notWOR ; Jump if Less (SF!=OF)seg010:1C3Eseg010:1C3E loc_1C06E: ; Logical ANDseg010:1C3E 01E and [bp+buildingPreReq1], 0FBFFhseg010:1C43seg010:1C43 loc_1C073: ; Logical ANDseg010:1C43 01E and [bp+buildingPreReq2], 0FFFFhseg010:1C47 01E mov di, 2seg010:1C4Aseg010:1C4A notWOR:Prerequisites are 4 bytes, but it's split up in 2 because 16-bit programs can't handle 4-byte values.The last command here, AND [value], FFFFh is totally useless, btw. Just the result of that "splitting up a long value" :Pbtw, the exception can be disabled simply by changing the checked house ID to something above 6 ;)In a hex editor, you can search for "81 66 E8 FF FB" (the actual disabling command), and then go back about 10 bytes until you find "26 80 7F 08 00", the house check. That 00 at the end is the house it executes this exception for.The disabling command seems to be a unique sequence in all versions, including even the demo, so it's easy to find. Quote Link to comment Share on other sites More sharing options...
MrFlibble Posted February 3, 2010 Author Share Posted February 3, 2010 Cool, thanks :) BTW, is the exception code nything like the one in C&C?btw, the exception can be disabled simply by changing the checked house ID to something above 6 ;)In a hex editor, you can search for "81 66 E8 FF FB" (the actual disabling command), and then go back about 10 bytes until you find "26 80 7F 08 00", the house check. That 00 at the end is the house it executes this exception for.Oh, I actually was more interetsted in expanding it to other sides (maybe something like "Check if House is NOT X" will work?), or at least switching it to different side :) Quote Link to comment Share on other sites More sharing options...
Nyerguds Posted February 3, 2010 Share Posted February 3, 2010 Cool, thanks :) BTW, is the exception code anything like the one in C&C?Wasn't the fact I knew pretty much exactly how it would look enough indication of that? ;)C&C has almost exactly the same code in reverse, to make the Nod buildings be equivalent as prerequisites to their GDI counterparts. This is done so the GDI buildings set as prerequisites serve as general indication of a vehicle factory, an infantry factory, a superweapon, a heavy defense structure (obelisk/AGT), so that if you want something to have "the superweapon building" as prerequisite, you just give it GDI's adv comm center, and it'll work with the Nod Temple too.The prerequisites system works by first making a bit mask with 1's for the buildings you have, to compare with the prerequisites bit mask of the construction option you're trying to give to the player.The equivalence code works by checking for the Nod counterparts of the aforementioned buildings, and every time it sees you got one of the Nod equivalents, it adds the GDI bit to it, meaning it pretends you got both. That way, a general "does the player have a Barracks building?" check can work :)This is not done the other way around though. If you specify that something needs the Hand of Nod to be built, it will not work if you got the GDI Barracks.Oh, I actually was more interested in expanding it to other sides (maybe something like "Check if House is NOT X" will work?), or at least switching it to different side :)well, the problem with expanding it is that you usually needs more space in the exe to actually put in something useful. In this case, you can free up some space with the useless "AND [value], FFFF" command, but that's still not enough for some decent coding.Enabling the exception if the house is NOT Harkonnen is rather simple, it's just adapting the condition of the jump it does after the check.Right now it says "jnz" ("Jump if Not Equal", byte 75h) right behind the house check. Change that to "Jump if Equal" ("jz", byte 74h) and the exception is enabled for all houses except for the Harkonnen (or whatever house you'd change the check to). For 3 playable houses, this means you can perfectly enable it for 1 (normal), 2 (inverted), 3 (remove the house check and jump by replacing it with 90h bytes) or 0 (force the jump past it by changing it to EBh, a normal "jmp") houses, meaning this one is fully customizable. Quote Link to comment Share on other sites More sharing options...
TrueBrain Posted February 4, 2010 Share Posted February 4, 2010 (..)In this case, you can free up some space with the useless "AND [value], FFFF" command, but that's still not enough for some decent coding.(..)You can change the useless AND into a forward jump to some unused block (as long as this piece of code is not in an overlay). Then you have much more room :) There are a nice amount of places the code can never come, so in theory you have room to extend ;) Quote Link to comment Share on other sites More sharing options...
Nyerguds Posted February 4, 2010 Share Posted February 4, 2010 Well there are no unused blocks, I don't know how to make new ones in the exe, and the 16-bit code doesn't allow far jumps. And I have no idea how a jump to a different section even work. It just isn't used in 32-bit code.Also, I've found that you need to be VERY careful with removing "unreachable" code or "unused" functions... sometimes it uses pretty dirty tricks to use them after all, or you're just missing some reference information in the database.I'm sticking to C&C95 :P Quote Link to comment Share on other sites More sharing options...
MrFlibble Posted February 4, 2010 Author Share Posted February 4, 2010 Wasn't the fact I knew pretty much exactly how it would look enough indication of that? ;)I'd say it was rather an indication of your expert knowledge in this field ;) Thanks for the info :)BTW, I wonder if a general comparison of the code of Dune II and Command & Conquer would be of any historical interest, revealing how the game engine evolved... Quote Link to comment Share on other sites More sharing options...
TrueBrain Posted February 4, 2010 Share Posted February 4, 2010 Well there are no unused blocks, I don't know how to make new ones in the exe, and the 16-bit code doesn't allow far jumps. And I have no idea how a jump to a different section even work. It just isn't used in 32-bit code.Also, I've found that you need to be VERY careful with removing "unreachable" code or "unused" functions... sometimes it uses pretty dirty tricks to use them after all, or you're just missing some reference information in the database.I'm sticking to C&C95 :PI have found a few blocks (via OpenDUNE C-ifications) which are impossible to ever be called .. stuff like: if (emu_ax < 0) { } (unsigned compare). It just never happens :) Even with all its dirty tricks, it is never called :)But okay .. using OpenDUNE is easier anyway, as it allows all and any modifications ;) Quote Link to comment Share on other sites More sharing options...
Nyerguds Posted February 4, 2010 Share Posted February 4, 2010 BTW, I wonder if a general comparison of the code of Dune II and Command & Conquer would be of any historical interest, revealing how the game engine evolved...Well the prerequisites system is still the same, that I can tell at least ;D Quote Link to comment Share on other sites More sharing options...
MrFlibble Posted February 5, 2010 Author Share Posted February 5, 2010 I have found a few blocks (via OpenDUNE C-ifications) which are impossible to ever be called .. stuff like: if (emu_ax < 0) { } (unsigned compare). It just never happens :) Even with all its dirty tricks, it is never called :)Does this mean that extra code can be added instead of those and it will work? :) There's also some extra space freed by Segra's "vanishing Houses bug" fix. Quote Link to comment Share on other sites More sharing options...
Nyerguds Posted February 6, 2010 Share Posted February 6, 2010 Well in a 32-bit program that would help... you can just jump from one tiny open spot to the next. In that case you'd be able to use 22 of these 27 bytes for actual code. (2 gone by making that actual code jump over the free part, 5 for the jump away after executing the added code). But as I said, I have no idea how long jumps work in 16-bit. As far as I can see, they kinda don't. You somehow have to set which section it should jump to, and then do a jump in there or something. Quote Link to comment Share on other sites More sharing options...
TrueBrain Posted February 6, 2010 Share Posted February 6, 2010 Well in a 32-bit program that would help... you can just jump from one tiny open spot to the next. In that case you'd be able to use 22 of these 27 bytes for actual code. (2 gone by making that actual code jump over the free part, 5 for the jump away after executing the added code). But as I said, I have no idea how long jumps work in 16-bit. As far as I can see, they kinda don't. You somehow have to set which section it should jump to, and then do a jump in there or something.16bit far jumps work the same as 32bit far jumps. You just have to make sure to repair the 'cs' value afterwards (but that is also true for 32bit). So using a far call is most likely easier, as then you can just do a return, which restores everything. You can only not jump to or from code in higher overlays, as they are dynamicly swapped in and out. The rest is staticly loaded, and can be used freely. Via OpenDUNE it should be easy to locate which are what. All files starting with cs__B are dynamic, all others static.Another random thought, if you really want to extend Dune2 itself: remove the sound, and load a patched file via the sound driver. Sound drivers are loaded in 0xAB000, so that is a set address. Just a random thought :) Quote Link to comment Share on other sites More sharing options...
Nyerguds Posted February 6, 2010 Share Posted February 6, 2010 yeah, I totally didn't get any of that. In 32 bit, all I do it "jmp wherever_I_want" and it does it. Not a clue what that cs value is you're talking about. I know very little about the whole theory behind assembler... I just know how to adapt it correctly, in 32 bit. And I haven't seen any cs in that.Do you mean you can use a 2-byte value as far jump parameter in 16-bit? The tool I use to convert asm code to bytecode only does 32-bit far jumps... would be annoying :P Quote Link to comment Share on other sites More sharing options...
TrueBrain Posted February 6, 2010 Share Posted February 6, 2010 yeah, I totally didn't get any of that. In 32 bit, all I do it "jmp wherever_I_want" and it does it. Not a clue what that cs value is you're talking about. I know very little about the whole theory behind assembler... I just know how to adapt it correctly, in 32 bit. And I haven't seen any cs in that.Do you mean you can use a 2-byte value as far jump parameter in 16-bit? The tool I use to convert asm code to bytecode only does 32-bit far jumps... would be annoying :POf course you need a 4 byte value .. 16bit machines have 20bit memory available ;) I suggest you read up on that a bit .. 'cs' = Code Segement. For that too, Google or something is your friend :)Maybe some day when I am bored, I will write a small proof-of-concept on the sound driver idea. Quote Link to comment Share on other sites More sharing options...
Nyerguds Posted February 6, 2010 Share Posted February 6, 2010 well as far as I know, code segments don't matter at all in 32 bit. I can jump between them or link to them without any problems. They're all part of one long addressing range.And I said "2-byte value as far jump parameter", not as jump command. I know the full command can be longer than 2 bits. Quote Link to comment Share on other sites More sharing options...
TrueBrain Posted February 7, 2010 Share Posted February 7, 2010 (..)And I said "2-byte value as far jump parameter", not as jump command. I know the full command can be longer than 2 bits.The memory address space on a 16bit machine is 20bits. You can't address this with 2 bytes. And as there is a far jump command, it has to be at least 3 bytes (but it is 4 bytes). This is called a CS:IP pair, CodeSegement + InstructionPointer. You should really look this up (using a search engine or what ever), as it is too much to explain here.Mind you, I talk about the parameter here too. The command is of no relevance to this talk. Quote Link to comment Share on other sites More sharing options...
MrFlibble Posted February 7, 2010 Author Share Posted February 7, 2010 Hm, I've noticed there are five code segnments in DUNE2.EXE that refer to the WOR: the first one, according to Segra, enables unit production within the structure, the second is the modifier for the Harkonnen WOR tech level and prerequisites that Nyerguds posted, the third is responsible for changin the WOR upgrade level from 6 to 4 for the Harkonnens, and there are two more, the purpose of which I currently do not know. Quote Link to comment Share on other sites More sharing options...
MrFlibble Posted February 15, 2010 Author Share Posted February 15, 2010 Two more entries at the OpenDUNE Developer's Blog were posted yesterday (TrueBrain has already submitted some of the new info in other threads here):[blog 2010-02-14] WinFlags / LoseFlags[blog 2010-02-14] Special Weapon Quote Link to comment Share on other sites More sharing options...
MrFlibble Posted March 11, 2010 Author Share Posted March 11, 2010 I've found some more interesting functions in Dune II (EU version):Here's the one that decides what color the score screen progress bars should be:A1 38 3A ; get House ID0B C0 ; if Harkonnen74 0C ; red score bar3D 01 00 ; if Atreides74 13 ; blue score bar3D 02 00 ; OR74 1A ; green score barEB 0C ; else, use the Atreides blue bar; Harkonnen red score barC7 46 FC 95 00 ; palette index for the darkest coulour in the remap schemeC7 46 FA 00 00 ; some reference to a function that creates the "glowing" effectEB 18 ; Atreides blue score barC7 46 FC A5 00 C7 46 FA 02 00 EB 0C ; Ordos green score barC7 46 FC B5 00 C7 46 FA 01 00 EB 00I could not identify the function that creates the glowing effect, but if the "base colour" referred to by the palette index (prior to calling that function) is changed, the colour of the score bar changes as a result of mixing the colours (e.g. I got a dark green colour by mixing the Sardaukar purple with something else). If the glowing effect index is changed to something else (e.g. C7 46 FA 03 00), the score bar no longer "glows", but retains the colour specified by the palette index above.The colour of the "enemy" score bar (which is always purple) is handled somewhere else, and I have been unable to find it yet.And here's the chunk that chooses House heralds for the map selection screen:A1 38 3A ; get House ID 0B C0 ; if Harkonnen 74 0C ; use Harkonnen herald3D 01 00 ; if Atreides 74 10 ; use Atreides herald3D 02 00 ; if Ordos 74 10 ; use Ordos heraldEB 09 ; else, use the Atreides heraldI've been unable to find the code that picks the heralds for the production screen as yet. It is probably more tricky, since the unplayable sides do not use any herald at all, but instead the space where the heralds should be is filled with a "copy-pasted" upper part of the top herald image.I also identified the code for the glowing selection boxes for the production screen:A1 38 3A ; get House ID 0B C0 ; if Harkonnen74 0C ; red selection box3D 01 00 ; if Atreides74 2F ; blue selection box3D 02 00 ; if Ordos74 1C ; green selection boxEB 2A ; else, white selection boxThe function itself that draws the selection boxes is pretty complicated, and I've been unable to figure out how to change the colours. Quote Link to comment Share on other sites More sharing options...
Jongware Posted March 11, 2010 Share Posted March 11, 2010 I could not identify the function that creates the glowing effect, but if the "base colour" referred to by the palette index (prior to calling that function) is changed, the colour of the score bar changes as a result of mixing the colours (e.g. I got a dark green colour by mixing the Sardaukar purple with something else). If the glowing effect index is changed to something else (e.g. C7 46 FA 03 00), the score bar no longer "glows", but retains the colour specified by the palette index above.Just checking: you are aware this is an old game, running in palettized 320x200 mode? The "glow" color may just be using one single color index, with some timer rotating the R, G, or B (or a combination) values of that index up and down. Perhaps it works like this: the RGB color of the index you found is copied to a buffer, and that gets read to draw a rectangle in the 'glow' color index (rather than directly in the color index of the lookup), and after that it's just that one index that gets updated.If you are able to make color indexed screenshots of various score screens, you might find that the differently coloured bars are, in fact, using the same index. It's what I would do, leaving the other 255 colors (a preciously low number) unchanged, to draw the rest of the screen with. Quote Link to comment Share on other sites More sharing options...
MrFlibble Posted March 11, 2010 Author Share Posted March 11, 2010 The "glow" color may just be using one single color index, with some timer rotating the R, G, or B (or a combination) values of that index up and down.That's what I suspect is the case, but the thing is that changing the actual palette index alone does not help, since there apparently are different hardcoded patterns that facilitate the playable Houses' score bars "glowing", and cannot be used with different colours. Quote Link to comment Share on other sites More sharing options...
Nyerguds Posted March 14, 2010 Share Posted March 14, 2010 I wouldn't be surprised if the game has a "find nearest colour" function which takes an RGB value and then looks through the entire palette to find the nearest match to it. I mean, C&C has only 256 colours too, and it does stuff like on-the-fly object resizes (with transparency, even) for the minimap. Quote Link to comment Share on other sites More sharing options...
MrFlibble Posted August 10, 2010 Author Share Posted August 10, 2010 As you know, the Fremen in the Sega version, unlike the PC version, have special icons different from regular troopers (also found among the PC version files), more hit points and weapon damage. However, as it turns out, Fremen troopers in the Sega version are not separate units, but modified Trooper(s) units. Ti_ from the Russian team focused on research and modding of Sega Mega Drive Dune: The Battle for Arrakis port has posted the relevant code related to the palace-summoned Fremen.ROM:00022EA2 lea (fremens_quanit).l,a1ROM:00022EA8 move.b (a1,d3.w),d6ROM:00022EAC ext.w d6ROM:00022EAE moveq #0,d5ROM:00022EB0 lea (fremens_utype).l,a4ROM:00022EB6 bra.w loc_22FFCROM:00022EBA ; ---------------------------------------------------------------------------ROM:00022EBAROM:00022EBA loc_22EBA: ; CODE XREF: SUPERWEAPON+336jROM:00022EBA addq.w #1,(word_FFC148).lROM:00022EC0 jsr (randomisation).l ; angle position randomisationsROM:00022EC6 move.w d0,(sp)ROM:00022EC8 move.w #1,-(sp) ; accurate positionsROM:00022ECC move.w #$1E,-(sp) ; range between fremensROM:00022ED0 move.l d4,-(sp)ROM:00022ED2 jsr sub_1168CROM:00022ED8 addq.l #8,spROM:00022EDA move.l d0,-(sp)ROM:00022EDC moveq #3,d0 ; fremen houseROM:00022EDE move.w d0,-(sp)ROM:00022EE0 move.w d0,-(sp)ROM:00022EE2 move.w #0,-(sp)ROM:00022EE6 jsr (random_for_xz).l ; fremen signle trooperROM:00022EEC addq.l #4,spROM:00022EEE add.w d0,d0ROM:00022EF0 move.w (a4,d0.w),-(sp)ROM:00022EF4 move.w #$FFFF,-(sp)ROM:00022EF8 jsr UNIT_CREATINGROM:00022EFE lea $A(sp),spROM:00022F02 movea.l a0,a2ROM:00022F04 subq.w #1,(word_FFC148).lROM:00022F0A move.l a2,d0ROM:00022F0C beq.w loc_22FFAROM:00022F10 lea $12(a2),a1ROM:00022F14 move.w (a1),d0ROM:00022F16 add.w d0,d0ROM:00022F18 move.w d0,(a1)Code to change icons:ROM:00029922 cmpi.b #3,8(a3) ; fremen house?ROM:00029928 bne.s unit_icons ; noROM:0002992A cmpi.b #$19,2(a3) ; wormROM:00029930 beq.s unit_icons ; yesROM:00029932 cmpi.b #3,2(a3) ; unit is 3 troopersROM:00029938 bne.s loc_2993E ; noROM:0002993A moveq #$5E,d3 ; 3 fremens iconROM:0002993C bra.s loc_29940ROM:0002993E ; ---------------------------------------------------------------------------ROM:0002993EROM:0002993E loc_2993E: ; CODE XREF: sub_294C2+476jROM:0002993E moveq #$68,d3 ; single fremen iconROM:00029940ROM:00029940 loc_29940: ; CODE XREF: sub_294C2+47AjROM:00029940 move.w d3,(sp)ROM:00029942 bra.s loc_2995AAnd here's the code for Fremen troopers' attack damage increase:ROM:000449BA move.w $54(a0),d7 ; read unit damage.......ROM:000449FE loc_449FE: ; CODE XREF: ROM:000449F6jROM:000449FE cmpi.b #3,8(a3) ; fremen house id?ROM:00044A04 bne.s loc_44A08 ; noROM:00044A06 lsl.w #2,d7 ; damage 4xROM:000449E2 loc_449E2: ; CODE XREF: ROM:000449D2jROM:000449E2 ; ROM:000449DEjROM:000449E2 cmpi.b #3,2(a3) ; troopersROM:000449E8 beq.s loc_449F2 ; yesROM:000449EA cmpi.b #5,2(a3) ; trooperROM:000449F0 bne.s loc_44A08 ; noSince there is evidence that the game code had undergone minimal changes during the Sega version development, I wonder if analogous code could be found in the PC version? Quote Link to comment Share on other sites More sharing options...
MrFlibble Posted August 21, 2010 Author Share Posted August 21, 2010 Ti_ changed the code in the Sega version so that the worms leave spice blooms when driven off the map:*d3=coord.*a2= adress; regs saved d3-d5, a2-a3 org $47160 jsr $43504(pc) jmp ($1ED0).w nop addq.l #4,sp cmpi.b #$19,2(a2) ; unit is worm? bne.s no_worm lea ($FFFFC068).w,a3 ; map scale lea ($714A8).l,a2 ; map cfg dat move.w #511,d5 move.w (a3),d4 add.w d4,d4 add.w (a2,d4.w),d3 ext.l d3 lsl.l #2,d3 movea.l ($4AA24).l,a3 adda.l d3,a3 move.w ($FFFFC228).w,d4 and.w d5,d4 move.w (a3),d3 andi.w #$FE00,d3 add.w d4,d3 move.w d3,(a3)no_worm movem.l (sp)+,d3-d5/a2-a3 rtsHe believes that the worms were supposed to return to the map after some time, and there are leftovers in the code for this which might be possible to reactivate. So basically he hopes to have unlimited spice on the map this way :) Quote Link to comment Share on other sites More sharing options...
Recommended Posts
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.