Ok, I'm going to upload a newer better version. I've been spending too much time on this little project, but I guess I'm enjoying and learning at the same time.
My main concern is how easy this could be integrated with platforms. While yeah python is extremely portable, it was kind of made after the days of DOS. Getting one that works takes some digging/trial and error especially with DOSBox. I'd like for it to work with DOSbox, mainly because that's what I'm using but there's some limitations such as no long file names, and I don't think it handles environment variables correctly either (one python installation kept looking for /usr/bin, even though I set the appropriate environment variables).
I also have a kinda crazy solution to this. Making a sort of 'monitoring' program with python and have it run on the host environment (instead of trying to make it fit into DOS with XCOM). Then when the switching is made from geoscape to tactical a batch file or simple program can wait until a certain file exists (which the monitoring system would make once it's done). Then the batch program would delete the file and continue on to tactical or geoscape. I am mainly thinking to do this to give python a bit more speed. The python that I can get to run on DOS box takes about 2-3 seconds to load (because of the 32-bit DOS extender). Once it is up, it's being emulated so the speed isn't exactly great either.
As a side note I tried to get python to compile to a 16-bit DOS program (I downloaded 1.5.2 source and hacked away). It has been very frustrating just getting to compile, then to maybe run. I did get an interpreter prompt a few times but I couldn't import any modules (including site) because it was out of memory. I started getting the impression I was trying to get a square peg into a round hole.
Alright, well if anyone's keeping track there's a pretty big change I did. I found out about the struct module in python that loads C-structs from files, much much faster than my parsing code. There's only a few file structures that aren't implemented but most of those are files we don't understand yet. Well on second thought I don't really have any 'maps' decoded, mainly because there are great tools for them already and using this structure would be tedious if not silly.
There's a module/folder datfile that contains all the data specific loaders that will be the 'back-end' for the project. They are basically there to provide a python-ic interface each of the files, and I'm actually kinda proud how much those can do.
I guess I'll go into detail a bit on how it's set up. Each file is split into records, many have lots of records like soldiers (250), while others only have 1 like saveinfo. To load a file simply import the datfile module with the same name as the file (or of the same format, ie obpos can be used for obpos2). Inside each of the files is a class of the same name but with 'dat' appended to the end. They simply need file to load (either when contructed or explicitly through load). Alright enough blabberin, I'll give an example
from datfile.soldier import Soldierdat
x = Soldierdat('missdat\\soldier.dat') #Don't forget to escape the back slashes in the path
print x[0].Name
x[0].iniFiring = 60 #Set the initial firing accuracy to 60
x[0].incFiring = 10 #set the increase in firing to 10, thus he has 70 accuracy
print x[0].getField("Rank") #Returns the formatted Rank of the soldier, x.Rank is the actual
#number stored in the file
x[0].Rank = 15 #This is an invalid value and will raise an exception unless...
x[0].unlock() #Unlocks the data checks to allow values that could not be obtained
x[0].enforce(True) #enables (or disables if argument is false) the lock
x[0].getEnforce() #returns the state of locking/enforcement
x[0]['Rank'] #this will also get the rank value (just the number)
x[0].pprint() #does a pretty print, basically giving long descriptions and formatting
#of the values ie Booleans will be 'Yes/No' Ranks, armor, etc will
#map to string values
x[0][1] #numbers can be used as well, they are in the order of file and also
#include 'Unknown' values that are left as raw strings. These values
#can be modified and can be reached by a name like _UNKNOWN_##
for s in x[0]:
print s #This will print all the raw values for the soldier
x.parseAll() #This will parse all the records, 250 in this case of Soldier.dat
#Normally the records are parsed on demand. Loading a file just places
#the entire file (as a string) in the variable. The record classes
#are not made until they are requested or explicitly parsed. Also
#parsing a record will remove any unsaved changes
for s in x:
print s.Name, s.Kills, s.Missions #Prints every soldier's (including dead and unused slots) name, kills and
#missions
Ok, I also have a psudo-front end for the soldiers called soldInfo.py (I'm sticking to 8x3 filenames) That has a slightly better interface for soldiers, and pprint() will print more like a grid (along with ASCII-ified stat bars). For example if s is an instance then s[0].firing would return the
total firing for the first soldier, and s[0].bravery will return the ingame result for bravery (stored differently in the file). Of course these values can't be changed mainly to save myself headaches. You can do s[0].data to get the same data interface as above so s[0].data.incFiring = 10 will work.
Ok, back to coding, just keep in mind I haven't really tested these much.