Jump to content

CnCNet Forums

Search In
  • More options...
Find results that contain...
Find results in...
Sign in to follow this  
pichorra

C&C95 Map expanding research

Recommended Posts

Well... I'm collecting information about how the game calculates and renders the cells. Any information are welcome.

 

What I know:

 

The max size of a C&C95 map is 64x64. If you edit the INI and try to put something large than it, the game would crash due a buffer overflow. So after digging into the game's code, I found that the map's andress is stored in .var:0053DDC0 . I found where the .exe calculates the length of the map:

 

004681B9: mov dword ptr[edx+28h], 40h

004681C0: mov dword ptr[edx+2Ch], 40h

 

after it, there is a integer multipler operator that calculates it's area. Then in some function where __wcpp_2_ctor_array__ is called, it get that value and times it by 0x21 and then, the array is allocated. So a map is:

 

typedef struct
{
         char unknown1[4];
         char tileset;
         char tilenumber;
         char[0x1B] unknown2; 
} Cell;

Cell[64][64] Map;

????

 

Of course, changing:

 

004681B9: mov dword ptr[edx+28h], 40h

004681C0: mov dword ptr[edx+2Ch], 40h

 

to

004681B9: mov dword ptr[edx+28h], 80h

004681C0: mov dword ptr[edx+2Ch], 80h

 

would avoid the game from crashing if you load an ini with 64 <= Length and Width <= 128, but the results are:

 

nwT3vbp.png

 

Thanks :)

Share this post


Link to post
Share on other sites

The game uses a macro in tons of spots the get a lower row of cells by doing some optimised integer mathematics with the assumption that the width of a map is 64.

Share this post


Link to post
Share on other sites
Any documentation about the macro?

Macros just mean that the code for it is actually copied into all these spots, instead of calling one central function. In other words, it's hell to find and modify them all.

Share this post


Link to post
Share on other sites

Also, my own fix for the radar crash when the screen res is larger than the map also just uses a hardcoded value of 0x1000.

 

You'd also need to fix all foundations of buildings and terrain pieces, since they all rely on a 64 cell wraparound for going one row of cells lower. And then I'm not even talking about the basic movement logic of moving a unit down one cell, which undoubtedly does that too. The reason I've never even considered expanding the map sizes is because it's such an insane amount of work.

Share this post


Link to post
Share on other sites

> The reason I've never even considered expanding the map sizes is because it's such an insane amount of work.

 

Same here.

Share this post


Link to post
Share on other sites

Turning it into a SVN project splitting the long job list in smaller parts and using the ticket system to prioritize and share the work with more people wouldn't be interesting?

Share this post


Link to post
Share on other sites

I hardly know how the macro works and what other code is used based on the 64x64 limit and 64 width, sorry.

Share this post


Link to post
Share on other sites

Yeah, but we will need more people.

 

Do you guys have an occourence of that macro in the code?

Macros are in the original C++ code, though. They don't always translate to the same things in the compiled assembler code, since the compiler just uses whatever registers are still unused in the function at that point, and whatever variables might've been inserted into the macro as arguments.

Share this post


Link to post
Share on other sites

If you were, to say, expand the map by 1 cell, would it still be an insane amount of work?

(not that I actually want the map expanded by 1 cell)

Share this post


Link to post
Share on other sites

If you were, to say, expand the map by 1 cell, would it still be an insane amount of work?

(not that I actually want the map expanded by 1 cell)

 

Theoretically, expanding the map by one cell is just as hard as expanding it by 64. I'm not a programmer but this research intrigues me and, as far as I understand, it's not the number of cells themselves that are the problem but the way the game counts them.

Share this post


Link to post
Share on other sites

If you were, to say, expand the map by 1 cell, would it still be an insane amount of work?

(not that I actually want the map expanded by 1 cell)

 

Theoretically, expanding the map by one cell is just as hard as expanding it by 64. I'm not a programmer but this research intrigues me and, as far as I understand, it's not the number of cells themselves that are the problem but the way the game counts them.

 

Exactly.

 

I've talked with one of my Teachers. As Nyerguds said, sometimes it doesn't generate the same code (it can generate a different code that do the same thing), especially a smart compiler like Watcom. Finding all occorences will be hard, but not impossible.

Share this post


Link to post
Share on other sites

The original watcom compiler was free/open source? last time I checked online (of the era). If that still fails you, you can always try the campaign server idea and simply make a huge map out of segments.

 

Iran came across some really interesting things, like saving maps states and exporting upon victory. Used in conjunction with a map resource generator, you could create an almost always persistent online world for the game (with endless borders).

Share this post


Link to post
Share on other sites

The original watcom compiler was free/open source? last time I checked online (of the era). If that still fails you, you can always try the campaign server idea and simply make a huge map out of segments.

 

No. It was a commercial compiler. Probably the older OpenWatcom is the most acurracy compiler we can get.

 

Iran came across some really interesting things, like saving maps states and exporting upon victory. Used in conjunction with a map resource generator, you could create an almost always persistent online world for the game (with endless borders).

I don't know about endless borders, but that would require an insane amout of RAM memory.

Share this post


Link to post
Share on other sites

Well, saving map states is kinda what they did in RA for those missions where you return to an expanded version of the same map later and get your old base there, no?

Share this post


Link to post
Share on other sites

Basically, the watcom excuse is bogus, there is plenty of documentation.

 

The RAM aint an issue.

 

Share this post


Link to post
Share on other sites

First of all, we need to find why the game simple does not drawn the other cells. I got busy with something else at the moment, so I will look at it when I got plenty of time, since that would require a lot of code digging. After then we can see what stuff can be implemented there.

Share this post


Link to post
Share on other sites

There are several ways I could point you to without giving code as to how to find all occurrences of a particular macro.

 

But firstly, you need to obtain the size of the code section and so on.  This is just reading the sections.

 

Then you will need a length disassembly engine.  You'll notice your displacements for edx is 0x28 and 0x2C respectively and the immediate value is 0x40.

 

You have several choices from here on out:

 

1)  Employ a neural network like solution.  It could be an adaline network, hopfield, bi-directional associative memory, and so on.  You'll want to realize that you are matching based on the similarity of the appearance of the code.

 

2)  Do a behavior based search, that is you define the behavior of the opcodes you are searching for and your pattern matcher only returns streams of opcodes that match the defined behavior.

 

3) 1 & 2.  Preferably.

 

4) Standard find pattern with wildcards and so on.

 

5) Some other stuff here

Share this post


Link to post
Share on other sites

The registers used with the offset changes and it seems the generated code sometimes does too.

Share this post


Link to post
Share on other sites

The registers used with the offset changes and it seems the generated code sometimes does too.

 

Even so, a well written neural network pattern searching tool would find it.

 

If that's a bother, I can only recommend using hardware breakpoints and notating all faulting addresses.  You are subject to possibly missing instances of the macro entirely if they don't access the memory location.  I.E. they only are called when a certain trigger is caused or situation.

Share this post


Link to post
Share on other sites

Do you think the game would play better on larger individual maps?

 

We are stuck to a 6 player limit at the moment as well.

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
Sign in to follow this  

  • Recently Browsing   0 members

    No registered users viewing this page.

×
×
  • Create New...