I would *really* like to get the active decompilers sharing data with each other, since otherwise there's just massive duplication of effort which could instead be directed towards more improvements to AC. The initial work of merging discovered functions would be significant, but I suspect would be quickly payed back by having three times as many people working on the project.
I want to see this happen because I like it when things get fixed and improved and think this would be a major step forward. I don't know exactly what I can do to help as a non-programmer, but if there's anything I can do to make it more likely I'm in (e.g. teaching people github, talking to people, organizing things).
I don't have decompilation in the normal sense; what I do have is notes on what various functions and variables do, and a step-by-step walkthrough of some functions.
However, I'm pretty sure that source code coming from decompiling the actual program would not be open source in the usual sense, but would be subject to all the copyright rules of the .exe. So we could mod it more easily, but that's about it.
I don't have decompilation in the normal sense; what I do have is notes on what various functions and variables do, and a step-by-step walkthrough of some functions.Okay, I'm sure that would be of interest to the others. Would you be willing to share?
Everything I've done is bundled in my IDA database. I will see about cleaning it up and making it available to you and whoever else who would like it in a couple weeks. I have spent a lot of time into making this database very comprehensive.
/*
* heap.h
* SMAC/X Project
* Brendan Casey
*
* v1.0 (6/30/14)
*
* Class to handle the low level heap operations to manage or allocate memory
* Removed an unused error flag (+0) and an unused parameter from squeeze()
*/
Well, I don't really have a change log myself. I have made some comments at the top of my header files where I've been keeping comments.Right, hm. It probably would be worth collecting information on that kind of change up somewhere.
One thing we'll need to worry about at some point is having a unified code format.
For example:Quote/*
* heap.h
* SMAC/X Project
* Brendan Casey
*
* v1.0 (6/30/14)
*
* Class to handle the low level heap operations to manage or allocate memory
* Removed an unused error flag (+0) and an unused parameter from squeeze()
*/
/*
* heap.h
* SMAC/X Project
* Brendan Casey
*
* v1.0 (6/30/14)
*
* Class to handle the low level heap operations to manage or allocate memory
* Removed an unused error flag (+0) and an unused parameter from squeeze()
*/
#pragma once
#include "stdafx.h"
#include "general.h" // mem_get()
class Heap
{
private:
LPVOID basePtr; // (+4) -> pointer to base memory address
LPVOID currentPtr; // (+8) -> current memory address position
size_t baseSize; // (+12) -> size of total memory
size_t freeSize; // (+16) -> size of free available memory
public:
// Constructor and Destructor
Heap(): basePtr(0), currentPtr(0), baseSize(0), freeSize(0) { }
~Heap() { shutdown(); }
// Get base total memory size
size_t getBaseSize() { return baseSize; }
// Get base memory address pointer
LPVOID getBasePtr() { return basePtr; }
// Destroy current heap and zero out all class variables
// LOCATION: 005D4580
void shutdown();
// Deflate heap of any free memory
// LOCATION: 005D45E0
void squeeze();
// Allocate memory based on requested size from parameter
// Return TRUE if memory allocation failed, otherwise FALSE
// LOCATION: 005D4620
BOOL init(size_t reqSize);
// Check if there is currently enough free memory for requested size from parameter
// If not, allocate more memory to heap in blocks of 1024 bytes until there is enough
// Return a memory pointer with address to requested size free
// LOCATION: 005D4680
LPVOID get(size_t reqSize);
};
/*
* heap.cpp
* SMAC/X Project
* Brendan Casey
*
* v1.0 (6/30/14)
*
* Class to handle the low level heap operations to manage or allocate memory
*/
#include "heap.h"
void Heap::shutdown()
{
if(basePtr){
free(basePtr);
}
basePtr = currentPtr = 0;
baseSize = freeSize = 0;
}
void Heap::squeeze()
{
size_t usedSize = baseSize - freeSize;
LPVOID newAddr = realloc(basePtr, usedSize);
if(newAddr){
basePtr = newAddr;
baseSize = usedSize;
freeSize = 0;
}
}
BOOL Heap::init(size_t reqSize)
{
if(basePtr){
shutdown();
}
basePtr = mem_get(reqSize);
if(basePtr){
currentPtr = basePtr;
baseSize = freeSize = reqSize;
return FALSE;
}
return TRUE; // failed to allocate memory
}
LPVOID Heap::get(size_t reqSize)
{
while(freeSize < reqSize){
LPVOID newAddr = realloc(basePtr, baseSize + 1024);
if(!newAddr){
CHAR szError[150]; // max size of string + three int(s) + extra
wsprintf(szError, "Aborting due to a heap shortage!\nBase size: %d\nFree size: %d\nRequested size: %d",
baseSize, freeSize, reqSize);
MessageBox(NULL, szError, "Heap Notice!!", MB_OK);
exit(3);
}
basePtr = newAddr;
currentPtr = LPVOID(size_t(basePtr) + baseSize - freeSize); // fix in case realloc shifts memory
baseSize += 1024;
freeSize += 1024;
}
LPVOID freeMemAddr = currentPtr;
freeSize -= reqSize;
currentPtr = LPVOID(size_t(currentPtr) + reqSize);
return freeMemAddr;
}
Inside base structure:
"Turns left to revolt: +7"
This is actually the number of turns left until assimilation of the base is complete. Once it goes down to zero, the former faction is set to current faction and the base no longer looks like the previous owners bases.
The info about base flags is useful, I only had rioting and golden age. :)
There are now 29 issues in the tracker (https://github.com/OpenSMACX/OpenSMACX/issues). I'd like some feedback on tagging from anyone who's interested at some point. There are also a bunch of possible bugs (https://github.com/OpenSMACX/OpenSMACX/labels/possible-bug) that need discussion.
Yitzi, would you be okay with me tracking feature requests from your thread on this?
Factions: Size 20CC. Faction 0 would have:
Nessus at 96D1EC
AI value for SUPPORT x at 96D080+4*x.
virtual mineral count: 946138+4Xfac#
Ahhhh, ok that makes sense why some things differed. I already have all alphax variables labeled in my database.
I was curious what you meant by Nessus inside faction struct and instead I found an array with pointers to addresses inside the string table.
I'm still not sure what virtual mineral count is tho.
Cool stuff. I encourage you to set up github for windows and keep your text file updated here https://github.com/OpenSMACX/OpenSMACX/tree/master/Information/DioI will post my text file once I have gathered as much information as I can in various areas :).
You're creating a file in a project you don't have write access to. We've created a fork of this project for you to commit your proposed changes to. Submitting a change will create the file in a new branch in your fork, so you can send a pull request.
Clicking on Clone from the github desktop downloads the contents of the repository onto your computer. Clicking the link leads me to an error loading page message.Okay, do you have a clone on your computer and github for windows? https://windows.github.com/ if yes to both, try moving the text file into the github folder on your computer and making a commit via github for windows? If it gives an error, please tell me exactly what causes it/what the error message is.
Dio--Any information on any routines or data will be useful. I think between what I have and what Scient has we're going to have 99% of the UI identified, but I've done nothing on the game logic, ai, etc., myself, and the Mac executable Scient found seems to mainly identify the UI classes rather than the game logic and AI routines that were probably straight C.Good to hear that my work will not go to waste. I have discovered a few things worth mentioning in the UI interface code but alot of what I found so far is related to script controls and AI behavior in regards to those scripts.
So really, I think any areas you want to focus on other than UI will be helpful.
Scient and any other C++ coders--so the main part that is going to suck is MSVC only allows the "naked" specification, which suppresses generation of function prologues and epilogues, outside of classes--you can't even use the specification for static members of a class. I looked to see if GNU C was any better, and it doesn't even allow the "naked" specification for 80x86 processors at all. I've always preferred Borland, which gives much more control over--well, everything--but that's a dead end long term since they basically went out of business nearly a decade ago, so I'm forcing myself to not use them.
The only solution I can think of is to wrap the .exe assembly in straight C __thiscall specifications and have a script add thunks for every non-virtual class method to the classes themselves. It's not a problem for virtual functions since those can be pointed directly at naked __thiscall's that aren't defined as class members, even though we know they really are class members.
...I've always preferred Borland, which gives much more control over--well, everything--but that's a dead end long term since they basically went out of business nearly a decade ago, so I'm forcing myself to not use them. ...
Attached below is most of my work so far plus a slightly revised and updated version of my Labels in the assembly code file.
Edit: Nobody is interested ???.
The procedure at 005002F0 moves arg 1 and 2 into the EAX and EDX registers respectively. Arg 3 takes a push value and moves it into the ECX register. The memory address of the diplomatic relationship with faction x is moved into the register EAX for these operations. Then it performs an AND command with the memory address for faction diplomatic relationships against the value in ECX. The final result for the AND command on the Diplomatic relationship address is then returned and often has a TEST command performed against itself with a conditional jump following.
This is just one of the many procedures that control AI diplomatic behavior but appears in many of the procedures for AI diplomatic behavior.
Glad it helped. Let me know if you find anything else you would like decompiled and I'll give it a go. :)
Of course! I've attached both decompiled files. Let me know if you come across anything else that would be helpful to decompile. :)
Here you go!
Hello again.I would love propouse something :
as the engine is the same as civilization 2 + voxel render,why doesnt use as base the
freeciv engine for the reimplementation you are doing based on your dissasmbly code.
Hello again.I would love propouse something :
as the engine is the same as civilization 2 + voxel render,why doesnt use as base the
freeciv engine for the reimplementation you are doing based on your dissasmbly code.
I would be wary of that. From a legal and ethical perspective, what we do with disassembling SMAC/X is ok based on ideas of fair use...and if we start using it significantly for something like freeciv (which is competing with the original in a way that probably precludes fair use), it seems to me that that could be an issue.
Hello again.I would love propouse something :
as the engine is the same as civilization 2 + voxel render,why doesnt use as base the
freeciv engine for the reimplementation you are doing based on your dissasmbly code.
I would be wary of that. From a legal and ethical perspective, what we do with disassembling SMAC/X is ok based on ideas of fair use...and if we start using it significantly for something like freeciv (which is competing with the original in a way that probably precludes fair use), it seems to me that that could be an issue.
Hello Yitzi.There are several ways of see this.I would try explain my view,but of course it is only my way of see the matter .
As far i know there are no legal issues if you dont use the assembly code as if ;
Hello,i asked a friend to decompile caviar player and caviar web pluggin using hexray for trying to understand this format.
Here goes the results.
http://pastebin.com/LcCxDNhP (http://pastebin.com/LcCxDNhP)
and the export files :
http://www.mediafire.com/file/ozt59x16hu69oj1/pluggin.rar (http://www.mediafire.com/file/ozt59x16hu69oj1/pluggin.rar)
http://www.mediafire.com/file/maiu0tz6qw3ppxv/caviar.rar (http://www.mediafire.com/file/maiu0tz6qw3ppxv/caviar.rar)
I hope this could be usefull.
The original files (i posted on other thread of this forum) :
http://www.mediafire.com/file/1539krs92y9hzj9/CVRPlay.rar (http://www.mediafire.com/file/1539krs92y9hzj9/CVRPlay.rar)
(it included the pdf patent with some info about this technology
and a mini-Faq i have created explaining this files
http://www.mediafire.com/file/td5n52vvdhz99h2/FAQ.txt (http://www.mediafire.com/file/td5n52vvdhz99h2/FAQ.txt)
By the way, I found the landmark creation procedures:
5C5EF0: jungle
5C5C70: crater
5C6DB0: volcano
5C7F40: mesa
5C8150: ridge
5C69E0: uranium
5C64A0: ruins
5C7750: unity
5C7A80: fossil
5C7540: nexus
5C7020: borehole
5C6200: sargasso
5C6740: dunes
5C6C40: fresh
5C83B0: geothermal
In all cases, arg1 and arg2 are position, with -1,-1 for random. Volcano has arg3 to determine if it comes from a special
event as opposed to map creation or scenario editor
Speaking of the patch documentation, the other thing that left me wondering was the "SELECT PLANETARY ORBIT" "80..100 million miles" option when generating a new map. It's the first thing the map generator asks yet I can't see if it affects anything? Another thread suggested it affects eco damage but not sure how to verify it. At least it should be explained in the readme or worded differently. The map in this game doesn't represent temperature per se, there's only humidity which already has its own setting.
SMACX global variable offset: 0x94A2B0
valid values: 0,1,2
The only function that references this global, outside of map configuration, is world_temperature(). This in turn is called by world_build() or world_climate(). The key one is world_climate() that gets called during terraforming, random events, planet busting, ecology functions and many others. It seems to get called on average between 10-20 turns.
IDA Pro 6.8.150423 with hexrays works. I think other 6.8 versions will work too.Decided to take a look at this again. If anyone has problems opening Scient's database, it is also pretty easy to import the annotations from these idc files. One should copy the lines containing MakeName or MakeComm and paste them into IDA's script input box. Then you should have most of the important functions with plain text names, no matter which version of IDA is in use.
idc files attached (database and separate typeinfo).
They're from my own database and have a handful more annotations than scient's database.
[Alpha Centauri]
Multi Debug=1
MAP* mapsq(int x, int y) {
int i = x/2 + (*tx_map_half_x) * y;
if (i >= 0 && i < *tx_map_half_x * *tx_map_axis_y)
return &((*tx_map_ptr)[i]);
else
return NULL;
}