Jump to content

C&C95 Map expanding research


pichorra

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 :)

Link to comment
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.

Link to comment
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.

Link to comment
Share on other sites

  • 4 weeks later...

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.

Link to comment
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.

Link to comment
Share on other sites

  • 1 month later...

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).

Link to comment
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.

Link to comment
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.

Link to comment
Share on other sites

  • 3 weeks later...

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

Link to comment
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.

Link to comment
Share on other sites

  • 3 months later...

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
  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...