#ifdef WINDOWS
#include "defs.h"
#include "noctis-d.h"
#include "noctis-0.h"
#include "noctis-2.h"

#include "randalg.h"
#include "mt.hpp"
#include "win.h"

#define NOCTISNGCPP
#include "noctis-ng.h"
const double deg = M_PI / 180;
extern Dword planets_labelled (Udword tgt_starFP, Udword galaxy);
extern void fix_remote_target();
extern float uno;
extern double avg_planet_ray[];
double nearstar_p_plate_tectonics [ng_maxbodies];
extern char vimana_shield;
extern char nsnp;

char *ng_planetd[] = { "INTERNALLY HOT",
				   "CRATERIZED NO ATMOSPHERE",
				   "THICK ATMOSPHERE",
				   "FELISIAN",
				   "CREASED NO ATMOSPHERE",
				   "THIN ATMOSPHERE",
				   "LARGE NOT CONSISTENT",
				   "ICY",
				   "QUARTZ",
				   "SUBSTELLAR OBJECT",
				   "COMPANION STAR" };


#ifdef OLD_STARMAP
extern Dword search_id_code (double id_code, char type);
#endif
#define advance 100000
#define halfadvance 50000

//code goes here
double ng_class_chance_planet[star_classes] = { .874485, .914468, .817765, .898260, .922681, .584804, .01, .5, .794597, .922681, .447214, .724780 };
double ng_class_chance_moon[] = { .25, .25, .577350, .629960, .577350, .577350, .849099, .577350, .629960, .858794, .858794 };


class StarData {
	public:
	Dword sect_x, sect_y, sect_z;
	Dword x, y, z;
	//double tempDxx;
	
	void Copy(StarData &data) {
		sect_x = data.sect_x;
		sect_y = data.sect_y;
		sect_z = data.sect_z;
		x = data.x;
		y = data.y;
		z = data.z;
		//tempDxx = data.tempDxx;
	}
	
	void Clear() {
		x = 0;
	}
	
	void NoStar() {
		x = 1;
		y = 0;
	}
	
	int IsInitialized() {
		return x!=0;
	}
	
	int HasStar() {
		return y!=0 && x!=0;
	}
};

StarData*** last_stardata0 = NULL;	//cost: about 87808 bytes of RAM
StarData*** last_stardata1 = NULL;	//cost: about 87808 bytes of RAM
StarData*** last_stardata = NULL;
StarData*** last_stardata_new = NULL;

char** command_conversions_from;
char** command_conversions_to;
int num_command_conversions;

double zmtrandom(double range) {
	return genrand_real2()*range - genrand_real2()*range;
}

double mtrandom(double range) {
	return genrand_real2()*range;
}

int ReadLine(FILE *inFile, char *string, int max) {
	//Reads a line of text from a text file:
	int nextByte = fgetc(inFile);
	int pos = 0;
	while (nextByte=='\n' || nextByte=='\r') {
		nextByte = fgetc(inFile);
	}

	//Loop until we reach a new-line character:
	while (nextByte!='\n' && nextByte!='\r' && pos<max) {
		//Check for end of file:
		if (nextByte==EOF) {
			string[pos]='\0';
			return 0;
		}
		string[pos++]=(char)nextByte;
		nextByte = fgetc(inFile);
	}

	string[pos]='\0';
	return 1;
}

int CountLines(FILE *file) {
	long pos = ftell(file);
	int nextByte = fgetc(file);
	int numLines = 0;
	int lastByte = 0;
	while (nextByte!=EOF) {
		if (nextByte=='\n') {
			numLines+=1;
		}
		lastByte = nextByte;
		nextByte = fgetc(file);
	}
	if (lastByte!='\n') {
		numLines+=1;
	}
	fseek(file, pos, SEEK_SET);
	return numLines;
}

/*
Udword rollChances(Udword[] chances, Udword numChances) {
	Udword total = 0;
	for (Udword i=0; i<numChances; i++) {
		total += chances[i];
	}
	Udword roll = genrand_int32(numChances);
	Udword result = -1;
	for (Udword i=0; i<numChances; i++) {
		roll -= chances[i];
		if (roll<=0) {
			result = i;
			break;
		}
	}
	if (result==-1 || result>=numChances) {
		fprintf(stderr, "Error: Invalid result %i from rollChances with numChances=%i\n", result, numChances);
	}
	return result;
}
*/

Dword rollNumPlanets(double chance, int max) {
	Bool cont = True;
	double roll;
	Dword planets = 0;
	while (cont) {
		roll = genrand_real2();
		if (roll < chance) {
			planets += 1;
			if (planets >= max) {
				cont = False;
			}
		} else {
			cont = False;
		}
	}	
	return planets;
}

void NewGalaxy_seedSystem() {
	nearstar_identity = nearstar_x/100000*nearstar_y/100000*nearstar_z/100000;
	SRAND ((long)nearstar_x%10000*(long)nearstar_y%10000*(long)nearstar_z%10000);
	Udword * nsid = (Udword*) (&nearstar_identity);
	Udword starSeed1 = *nsid;
	Udword starSeed2 = *(nsid+1);
	//unsigned long temp = 0;
	//fprintf(stderr, "sizeof(starSeed1)=%i, sizeof(temp)=%i\n", sizeof(starSeed1), sizeof(temp));
	Udword initKeys[5];
	initKeys[0] = nearstar_sx;
	initKeys[1] = nearstar_sy;
	initKeys[2] = nearstar_sz;
	initKeys[3] = starSeed1;
	initKeys[4] = starSeed2;
	
	init_by_array((unsigned long*) initKeys, 5);
}

FastBool NewGalaxy_prepare_nearstar(FastBool option) {
	#ifdef WINDOWS
	if (vimana_shield==3) {
		vimana_shield = 0;
	}
	#endif
	
	if (current_galaxy==0) {
		return False;
	} else {
		int    n, c, q, r, s, t;
		double key_radius;
		
		//For new temperature stuff (SL)
		nearstar_mass = -1;
		nearstar_surfaceTemperature = -1;
		nearstar_temperatureTransmission =-1;
		
		//Commenting this out might or might not cause problems - not sure yet. (SL)
		//if (!_delay) {
		//DebugPrintf(0, "A Clock: %li.", clock());
		#ifndef OLD_STARMAP
		if (ap_target_sx==0x7FFFFFFF && ap_target_sy==0x7FFFFFFF && ap_target_sz==0x7FFFFFFF) {
			//DebugPrintf(0, "SecCoords Unknown #1 in prepare_nearstar!");
			//Sector coords unknown; find them!
			Dword retval = getSectorCoords(ap_target_x, ap_target_y, ap_target_z, &ap_target_sx, &ap_target_sy, &ap_target_sz);
			if (retval==-1) {
				if (charge!=0) status ("ACK! CAN'T FIND SYSTEM", 200);
				disableR9aBugMessage();
			} else if (retval==-2) {
				enableR9aBugMessage();
			} else {
				disableR9aBugMessage();
			}
		} else {
			disableR9aBugMessage();
		}
		//DebugPrintf(0, "B Clock: %li.", clock());
		#endif
		if (option==COPY_NEARSTAR_FROM_AP_TARGET) {
			nearstar_class = ap_target_class;
			nearstar_x = ap_target_x;
			nearstar_y = ap_target_y;
			nearstar_z = ap_target_z;
			nearstar_sx = ap_target_sx;
			nearstar_sy = ap_target_sy;
			nearstar_sz = ap_target_sz;
			nearstar_ray = ap_target_ray;
			nearstar_spin = ap_target_spin;
			nearstar_r = ap_target_r;
			nearstar_g = ap_target_g;
			nearstar_b = ap_target_b;
		//}
		}
		//DebugPrintf(0, "C Clock: %li.", clock());
		#ifndef OLD_STARMAP
		if (ap_reached && nearstar_sx==0x7FFFFFFF && nearstar_sy==0x7FFFFFFF && nearstar_sz==0x7FFFFFFF) {
			//Sector coords unknown; find them!
			//DebugPrintf(0, "SecCoords Unknown #2 in prepare_nearstar!");
			Dword retval = getSectorCoords(nearstar_x, nearstar_y, nearstar_z, &nearstar_sx, &nearstar_sy, &nearstar_sz);
			if (retval==-1) {
				if (charge!=0) status ("ACK! CAN'T FIND SYSTEM", 200);
			} else if (retval==-2) {
				enableR9aBugMessage();
			}
		}
		#endif
		
		s_m = qt_M_PI * nearstar_ray * nearstar_ray * nearstar_ray * 0.01e-7;

		NewGalaxy_seedSystem();
		
		int numStarPairs = 0;
		if (nearstar_class!=8) {
			nearstar_nop = rollNumPlanets(ng_class_chance_planet[nearstar_class], ng_maxplanets);
		} else {
			numStarPairs = rollNumPlanets(0.25, 10)+1;
			nearstar_nop = numStarPairs;
		}
		fprintf(stderr, "nearstar_nop: %i\n", nearstar_nop);
		
		/* Prima estrazione (pressoch‚ casuale, non realistica). */

		for (n=0; n<nearstar_nop; n++) {
			nearstar_p_owner[n]	 = -1;
			nearstar_p_orb_orient[n] = (double) deg * (genrand_real2()*360.0);
			nearstar_p_orb_seed[n]   = 3.0 * (n*n+1) * nearstar_ray + (float) genrand_real2()*(300.0 * nearstar_ray) / 100.0;
			nearstar_p_tilt[n]       = zmtrandom (10.0*nearstar_p_orb_seed[n]) / 500.0;
			nearstar_p_orb_tilt[n]   = zmtrandom (10.0*nearstar_p_orb_seed[n]) / 5000.0;
			nearstar_p_orb_ecc[n]    = 1.0 - (genrand_real2()* (nearstar_p_orb_seed[n] + 10.0*fabs(nearstar_p_orb_tilt[n]))) / 2000.0;
			nearstar_p_ray[n]        = genrand_real2() * (nearstar_p_orb_seed[n]) * 0.001 + 0.01;
			nearstar_p_ring[n]	 = zmtrandom (nearstar_p_ray[n]) * (1 + genrand_real2() * 10.0);
			if (nearstar_class != 8)
				nearstar_p_type[n] = (char) mtrandom (planet_types);
			else {
				//if (random(2)) {
					nearstar_p_type[n] = 10;
					nearstar_p_orb_tilt[n] *= 100;
				//}
				//else
				//	nearstar_p_type[n] = (char) mtrandom (planet_types);
			}
			if (nearstar_class==2||nearstar_class==7||nearstar_class==15)
				nearstar_p_orb_seed[n] *= 10;
		}

		/* Aumento delle probabilit… di pianeti abitabili su classe zero. */

		if (!nearstar_class) {
			if (genrand_real2()<.25) nearstar_p_type[2] = 3;
			if (genrand_real2()<.25) nearstar_p_type[3] = 3;
			if (genrand_real2()<.25) nearstar_p_type[4] = 3;
		}

		/* Eliminazione di pianeti impossibili attorno a certe stelle.
		   Fase 1: solo quelli impossibili per tipo di stella. */

		for (n=0; n<nearstar_nop; n++) {
			switch (nearstar_class) {
				case 2: 
					Dword attempts = 0;
					while (nearstar_p_type[n]==3 && attempts<3) {
						nearstar_p_type[n] = (char) mtrandom (10);
						attempts+=1;
					}
					break;
				case 5: 
					while ((nearstar_p_type[n]==6||
						   nearstar_p_type[n]==9) && attempts<3) {
						nearstar_p_type[n] = (char) mtrandom (10);
					}
					break;
				case 7:	
					if (genrand_real2()>=.01) {
						nearstar_p_type[n] = 9;
					}
					break;
				case 9: while (nearstar_p_type[n]!=0&&
						   nearstar_p_type[n]!=6&&
						   nearstar_p_type[n]!=9 && attempts<6)
						nearstar_p_type[n] = (char) mtrandom (10);
					break;
				case 11:while (nearstar_p_type[n]!=1 && 
						   nearstar_p_type[n]!=7 && attempts<6)
						nearstar_p_type[n] = (char) mtrandom (10);
			}
		}

		/* Eliminazione di pianeti impossibili attorno a certe stelle.
		   Fase 2: solo quelli impossibili per distanza dalla stella. */

		for (n=0; n<nearstar_nop; n++) {
			switch (nearstar_p_type[n]) {
				case 0:
					if (genrand_real2()<.125)
						nearstar_p_type[n] ++;
					break;
				case 3:
					//if ((n<2)||(n>6)||(nearstar_class&&random(4))) {
					if ((n<2) || (n>6) || (nearstar_class && genrand_real2()<0.25)) {
						if (genrand_real2()<.5)
							nearstar_p_type[n]++;
						else
							nearstar_p_type[n]--;
					}
					break;
				case 7:
					if (n<7) {
						if (genrand_real2()<.5)
							nearstar_p_type[n] --;
						else if (genrand_real2()<.95)
							nearstar_p_type[n] -= 2;
					}
					break;
			}
		}

		/* Estrazione dei satelliti naturali (lune). */

		nearstar_nob = nearstar_nop;

		if (nearstar_class==2||nearstar_class==7||nearstar_class==15)	//What the hell is 15? (SL)
			goto no_moons;

		for (n=0; n<nearstar_nop; n++) {
			// (t=) Numero di satelliti per pianeta.
			s = nearstar_p_type[n];
			if (n < 2) {
				t = 0;
				if (s == 10 && nearstar_class == 8)
					t = rollNumPlanets(ng_class_chance_planet[nearstar_class], ng_maxplanets);
			}
			else
				t = rollNumPlanets(ng_class_chance_moon[nearstar_p_type[n]], 40);
			if (nearstar_nob + t > ng_maxbodies)
				t = ng_maxbodies - nearstar_nob;
			// Caratteristiche dei satelliti.
			for (c=0; c<t; c++) {
				q 			 = nearstar_nob + c;
				nearstar_p_owner[q]	 = n;
				nearstar_p_moonid[q]	 = c;
				nearstar_p_orb_orient[q] = (double) deg * (genrand_real2()*360.0);
				nearstar_p_orb_seed[q]   = (c*c+4) * nearstar_p_ray[n] + (float) zmtrandom (300 * nearstar_p_ray[n]) / 100;
				nearstar_p_tilt[q]       = zmtrandom (10*nearstar_p_orb_seed[q]) / 50;
				nearstar_p_orb_tilt[q]   = zmtrandom (10*nearstar_p_orb_seed[q]) / 500;
				nearstar_p_orb_ecc[q]    = 1 - (double) mtrandom (nearstar_p_orb_seed[q] + 10*fabs(nearstar_p_orb_tilt[q])) / 2000;
				nearstar_p_ray[q]        = (double) mtrandom (nearstar_p_orb_seed[n]) * 0.05 + 0.1;
				nearstar_p_ring[q]	 = 0;
				nearstar_p_type[q]       = mtrandom (planet_types);
				// Estrazione tipologia di satellite:
				r = nearstar_p_type[q];
				// Un oggetto substellare come luna?
				// Ce lo pu• avere solo una stella compagna.
				if (r==9 && s != 10) r = 2;
				// Un gigante gassoso come luna?
				// Ce lo pu• avere solo un oggetto substellare,
				// o una stella compagna in un sistema multiplo.
				if (r==6 && s < 9) r = 5;
				// "Raffreddamento" satelliti esterni, lontani sia
				// dal pianeta che dalla stella, in genere congelati.
				if (n > 7 && mtrandom(c)) r = 7;
				if (n > 9 && mtrandom(c)) r = 7;
				// Lune relativamente grandi possono esistere solo
				// attorno a pianeti gassosi ed oggetti substellari.
				// Invece, i simil-lunari(1), i simil-marziani(5),
				// le lune come Io(0), e quelle come Europa(7),
				// possono esistere anche attorno ad altri tipi di
				// pianeti, ma di certo in scala piuttosto ridotta.
				if (r==2 || r==3 || r==4 || r==8) {
					if (s != 6 && s < 9)
						r = 1;
				}
				// Attorno ai giganti gassosi, se il test precedente
				// Š passato (s = 6/9/10, gassoso/substellare/stella),
				// bŠ, possono anche esserci, a certe condizioni,
				// delle lune abitabili. Per queste, per•, la stella
				// dev'essere in genere di classe zero ed il pianeta
				// gigante non dev'essere troppo lontano dalla stella.
				// C'Š invece uguale probabilit… di trovare mondi
				// abitabili attorno agli oggetti substellari: al di
				// l… della distanza dalla stella, tali lune possono
				// essere scaldate abbastanza da una stella mancata.
				if (r==3 && s < 9) {
					if (n > 7)
						r = 7;
					if (nearstar_class && mtrandom(4))
						r = 5;
					if (nearstar_class == 2 ||
						nearstar_class == 7 ||
						nearstar_class == 11)
						r = 8;
				}
				// Una luna ghiacciata Š esclusa, prima di arrivare
				// almeno alla sesta orbita planetaria, perch‚ fa
				// comunque troppo caldo.
				if (r==7 && n <= 5) r = 1;
				// Ma lune ghiacciate sono comunque molto pi—
				// frequenti se la stella Š molto piccola e fredda:
				// un pianeta in genere pu• avere meccanismi interni
				// che lo scaldano. Una luna no.
				if ((nearstar_class==2||nearstar_class==5||
					 nearstar_class==7||nearstar_class==11)
					 && mtrandom(n)) r = 7;
				// Fine estrazione tipologia di satellite.
				nearstar_p_type[q] = r;
			}
			nearstar_nob += t;
		}
		fprintf(stderr, "nearstar_nob: %i\n", nearstar_nob);
		
		/* Ri-Normalizzazione delle dimensioni dei pianeti,
		   normalizzazione delle orbite in base al principio di Keplero.
		   Il principio di Keplero stabilisce che il raggio dell'orbita di
		   un pianeta tende ad essere simile alla sommatoria dei raggi delle
		   orbite di tutti i pianeti interni ad esso. Per•, per un numero di
		   pianeti maggiore di 8, il principio non Š pi— valido. Noctis
		   rinormalizza le orbite oltre l'ottava, aggiungendo a tali orbite
		   il 22% circa della sommatoria delle precedenti. Ovvero:

		   SE si applica il principio di Keplero
		   per (ad esempio) 12 pianeti, e per Raggio Prima Orbita = 1,
		   allora i raggi delle altre orbite sarebbero:
		   *	1  2  3  6  12  24  48  96  192  384  768  1536

		   SE si applica l'organizzazione di Noctis, il tutto diventerebbe:
		   *	1  2  3  6  12  24  48  96  117  143  174  212

		   Il 22% non Š un valore a caso: rappresenta all'incirca il rapporto
		   fra i raggi delle orbite di Plutone e di Urano. Plutone Š circa del
		   22% pi— lontano dal Sole di Urano, cioŠ l'ottava orbita. Ovvio che
		   non significa che un sistema planetario pi— vasto debba per forza
		   avere orbite organizzate in questo modo, anche perch‚ Plutone non
		   Š certo un pianeta "naturalmente" formatosi assieme agli altri, ma
		   pi— probabilmente un satellite sfuggito o un corpo della nube di
		   Oort catturato dal Sole. Per• bisogna dire che le influenze delle
		   orbite dei pianeti interni, col proseguire della successione di
		   Keplero, diventano sempre meno significative. Penso che tale
		   successione, semplicemente, debba essere in qualche modo limitata,
		   a un certo punto: Š improbabile che ci siano pianeti in orbita
		   stabile a distanze come quelle risultanti per le orbite oltre
		   l'ottava. Noctis annovera anche stelle con ben 20 pianeti!

		   Come ultima annotazione, il raggio delle orbite Š influenzato
		   anche dalla massa dei pianeti. Pianeti che hanno all'interno delle
		   loro orbite giganti gassosi saranno un po' pi— lontani della media
		   perch‚ altrimenti le loro orbite potrebbero essere troppo
		   destabilizzate dalla massa dei giganti. */

	no_moons:
		key_radius = nearstar_ray * planet_orb_scaling;
		if (nearstar_class == 8) key_radius *= 2;
		if (nearstar_class == 2) key_radius *= 16;
		if (nearstar_class == 7) key_radius *= 18;
		if (nearstar_class == 11) key_radius *= 20;
		for (n=0; n<nearstar_nop; n++) {
			nearstar_p_ray[n] = avg_planet_ray[nearstar_p_type[n]]
					  + avg_planet_ray[nearstar_p_type[n]] * zmtrandom (100) / 200;
			nearstar_p_ray[n] *= avg_planet_sizing;
			nearstar_p_orb_ray[n] = key_radius + key_radius * zmtrandom (100) / 500;
			nearstar_p_orb_ray[n] += key_radius * avg_planet_ray[nearstar_p_type[n]];
			if (n < 8)
				key_radius += nearstar_p_orb_ray[n];
			else
				key_radius += 0.22 * nearstar_p_orb_ray[n];
		}

		/* Ri-Normalizzazione delle dimensioni delle lune,
		   normalizzazione orbite lunari in base al principio di Keplero,
		   a sua volta rielaborato come nelle precedenti annotazioni,
		   solo che la limitazione avviene per orbite oltre la terza al 12%,
		   ed Š molto pi— effettiva oltre l'ottava orbita (al 2.5%). */

		n = nearstar_nop;
		while (n < nearstar_nob) {
			q = 0;
			c = nearstar_p_owner[n];
			key_radius = nearstar_p_ray[c] * moon_orb_scaling;
			while (n<nearstar_nob && nearstar_p_owner[n] == c) {
				nearstar_p_ray[n] = avg_planet_ray[nearstar_p_type[n]]
						  + avg_planet_ray[nearstar_p_type[n]] * zmtrandom (100) / 200;
				nearstar_p_ray[n] *= avg_moon_sizing;
				nearstar_p_orb_ray[n] = key_radius + key_radius * zmtrandom (100) / 250;
				nearstar_p_orb_ray[n] += key_radius * avg_planet_ray[nearstar_p_type[n]];
				if (q < 2) key_radius += nearstar_p_orb_ray[n];
				if (q >= 2 && q < 8) key_radius += 0.12 * nearstar_p_orb_ray[n];
				if (q >= 8) key_radius += 0.025 * nearstar_p_orb_ray[n];
				q++;
				n++;
			}
		}
		
		//Environmental changes
		for (n = 0; n < nearstar_nob; n++) {
			double roll = genrand_real2() + genrand_real2() + genrand_real2();
			double divby = 3.0;
			roll += (nearstar_p_ray[n]*100.0)-1.0;
			if (roll<0.0) roll=0.0;
			if (divby>0.0 && roll>0.0) {
				nearstar_p_plate_tectonics[n] = roll / divby;
			} else {
				nearstar_p_plate_tectonics[n] = roll;
			}
			fprintf(stderr, "plate tectonics for planet %i, planet type %s, are %f.\n", n, ng_planetd[nearstar_p_type[n]], nearstar_p_plate_tectonics[n]);
			//Average for a felisian planet would be around .533333?
		}

		/* Eliminazione di anelli improbabili. */

		for (n = 0; n < nearstar_nop; n++) {
			// A meno di un raggio e mezzo dal centro del pianeta,
			// sar… un po' difficile trovarci un anello stabile.
			nearstar_p_ring[n] = 0.75 * nearstar_p_ray[n] * (2 + mtrandom(3));
			// I pianeti piccoli raramente hanno degli anelli.
			// Non hanno abbastanza massa per frantumare
			// una luna che arrivi troppo vicina.
			s = nearstar_p_type[n];
			if (s != 6 && s != 9) {
				if (genrand_real2()<.2)
					nearstar_p_ring[n] = 0;
			}
			else {
				if (genrand_real2()<.5)
					nearstar_p_ring[n] = 0;
			}
		}

		/* Conteggio degli oggetti che hanno un nome (suggerimento di Ryan) */

		nearstar_labeled = 0;
		Udword tgt_starFP = system_labelled(nearstar_sx, nearstar_sy, nearstar_sz, current_galaxy);
		nearstar_labeled=planets_labelled(tgt_starFP, current_galaxy);
		/* Reset dei periodi di rotazione
		   (vengono calcolati con la superficie) */

		for (n = 0; n < nearstar_nob; n++)
			nearstar_p_rtperiod[n] = 0;
		
		for (n = 0; n < nearstar_nop; n++) {
			planet_xyz (n);
			//plx, ply, plz
		}
		return True;
	}
}

Word NewGalaxy_ap_target_starnop() {
	if (current_galaxy==0) {
		return -1;
	} else {
		double ap_target_identity = ap_target_x/100000*ap_target_y/100000*ap_target_z/100000;
		SRAND ((long)ap_target_x%10000*(long)ap_target_y%10000*(long)ap_target_z%10000);
		Udword * aptid = (Udword*) (&ap_target_identity);
		Udword starSeed1 = *aptid;
		Udword starSeed2 = *(aptid+1);
		//unsigned long temp = 0;
		//fprintf(stderr, "sizeof(starSeed1)=%i, sizeof(temp)=%i\n", sizeof(starSeed1), sizeof(temp));
		Udword initKeys[5];
		initKeys[0] = ap_target_sx;
		initKeys[1] = ap_target_sy;
		initKeys[2] = ap_target_sz;
		initKeys[3] = starSeed1;
		initKeys[4] = starSeed2;
		
		init_by_array((unsigned long*) initKeys, 5);
		
		int numStarPairs = 0;
		if (nearstar_class!=8) {
			nearstar_nop = rollNumPlanets(ng_class_chance_planet[ap_target_class], ng_maxplanets);
		} else {
			numStarPairs = rollNumPlanets(0.25, 10)+1;
			nearstar_nop = numStarPairs;
		}
		return nearstar_nop;
	}
}

Dword plotStar(StarData *data, float starneg, Uword limits, Dword min_xy) {
	float xx, yy, zz, z2, rz, inv_rz;
	Dword temp_x, temp_y, temp_z, sect_x, sect_y, sect_z, rx, ry;
	temp_x = data->x;
	temp_y = data->y;
	temp_z = data->z;
	sect_x = data->sect_x;
	sect_y = data->sect_y;
	sect_z = data->sect_z;
	Dword temp;
	
	asm {
	PUSHAD
	mov esi, [adapted]
	}
	ispresent:asm {	fild dword ptr temp_z
	fsub dzat_z
	fst zz
	fmul opt_tcosbeta
	fild dword ptr temp_x
	fsub dzat_x
	fst xx
	fmul opt_tsinbeta
	fsubp
	fst z2
	fmul opt_tcosalfa
	fild dword ptr temp_y
	fsub dzat_y
	fst yy
	fmul opt_tsinalfa
	faddp
	fst rz
	fcomp starneg
	fstsw ax
	sahf
	jnb _123stella
	jmp endgame }
_123stella:asm {fld xx
	fmul opt_pcosbeta
	fld zz
	fmul opt_psinbeta
	faddp
	fld uno
	fdiv rz
	fst inv_rz
	fmulp
	fistp rx
	#ifdef WINDOWS
	movsx edi, word ptr rx
	add edi, x_centro
	cmp edi, 10
	#else
	mov di, word ptr rx
	add di, x_centro
	cmp di, 10
	#endif
	ja _x_low_ok
	jmp endgame }
_x_low_ok:asm {
	#ifdef WINDOWS
	//NOTVALID: Depends on display width being 320.
	cmp edi, 310
	#else
	cmp di, 310
	#endif
	jb _x_high_ok
	jmp endgame }
_x_high_ok:asm{	fld yy
	fmul opt_pcosalfa
	fld z2
	fmul opt_psinalfa
	fsubp
	fmul inv_rz
	fistp ry
	sub word ptr ry, 2
	#ifdef WINDOWS
	movsx ebx, word ptr ry
	add ebx, y_centro
	cmp ebx, 10
	#else
	mov bx, word ptr ry
	add bx, y_centro
	cmp bx, 10
	#endif
	ja _y_low_ok
	jmp endgame }
_y_low_ok:asm {
	#ifdef WINDOWS
	//NOTVALID: Depends on display width being 320.
	cmp ebx, 190
	#else
	cmp bx, 190
	#endif
	jb _y_high_ok
	jmp endgame }
_y_high_ok: asm {
	#ifdef WINDOWS
	shl ebx, 1
	add edi, dword ptr riga[ebx*2]
	#else
	shl bx, 1
	add di, word ptr riga[bx]
	#endif
	cmp ap_targetting, 1
	je newgame
	#ifdef WINDOWS
	cmp byte ptr [esi+edi], 68	//cmp byte ptr [esi+edi+4], 68	//REMOVED4
	#else
	cmp byte ptr es:[di+4], 68
	#endif
	je endgame
	mov ax, limits
	#ifdef WINDOWS
	cmp byte ptr [esi+edi], ah	//cmp byte ptr [esi+edi+4], ah	//REMOVED4
	#else
	cmp byte ptr es:[di+4], ah
	#endif
	jb endgame
	#ifdef WINDOWS
	cmp byte ptr [esi+edi], al	//cmp byte ptr [esi+edi+4], al	//REMOVED4
	#else
	cmp byte ptr es:[di+4], al
	#endif
	ja endgame }
newgame: asm {	fld rz
	fistp temp
	mov cl, 13
	add cl, field_amplificator
	#ifdef WINDOWS
	mov edx, dword ptr temp
	shr edx, cl
	#else
	db 0x66; mov dx, word ptr temp
	db 0x66; shr dx, cl
	#endif
	mov al, 63
	sub al, dl
	jc colorout
	#ifdef WINDOWS
	mov dl, byte ptr [esi+edi]	//mov dl, byte ptr [esi+edi+4]	//REMOVED4
	and byte ptr [esi+edi], 0xC0	//and byte ptr adapted[edi], 0xC0
	#else
	mov dl, es:[di+4]
	and byte ptr es:[di+4], 0xC0
	#endif
	and dl, 0x3F
	add al, dl
	cmp al, 63
	jbe colorin
	mov al, 63 }
colorin: asm {
	#ifdef WINDOWS
	or byte ptr [esi+edi], al	//or byte ptr [esi+edi+4], al	//REMOVED4
	#else
	or es:[di+4], al
	#endif
}
colorout:asm {	cmp ap_targetting, 1
	je extend }
endgame: asm	jmp next
extend:
/*
	'extend' does this:
		f1=rx*rx
		f2=ry*ry
		f1+=f2
		temp=ft
		temp = ry*ry + rx*rx
		if temp >= min_xy goto next
		(else)
		min_xy = temp
		store ap_target_? coords from temp_? coords
	(SL)
*/
	asm {
	#ifdef WINDOWS
	fild rx
	fild rx
	fmulp
	fild ry
	fild ry
	fmulp
	#else
	fild rx
	fmul st(0), st(0)
	fild ry
	fmul st(0), st(0)
	#endif
	faddp
	fistp temp
	MOV_EAX_DWORD_PTR temp
	#ifdef WINDOWS
	cmp eax, dword ptr min_xy
	#else
	db 0x66; cmp ax, word ptr min_xy
	#endif
	jnb next
	#ifdef WINDOWS
	mov dword ptr min_xy, eax
	#else
	db 0x66; mov word ptr min_xy, ax
	#endif
	fild dword ptr temp_x
	fstp ap_target_x
	fild dword ptr temp_y
	fstp ap_target_y
	fild dword ptr temp_z
	fstp ap_target_z
	#ifdef WINDOWS
	mov eax, dword ptr sect_x
	mov dword ptr ap_target_sx, eax
	mov eax, dword ptr sect_y
	mov dword ptr ap_target_sy, eax
	mov eax, dword ptr sect_z
	mov dword ptr ap_target_sz, eax
	#else
	db 0x66; mov ax, word ptr sect_x
	db 0x66; mov word ptr ap_target_sx, ax
	db 0x66; mov ax, word ptr sect_y
	db 0x66; mov word ptr ap_target_sy, ax
	db 0x66; mov ax, word ptr sect_z
	db 0x66; mov word ptr ap_target_sz, ax
	#endif
	}
	next:
	asm {
		POPAD
	}
	return min_xy;
}

FastBool NewGalaxy_sky(Uword limits) {
	if (current_galaxy==0) {
		return False;
	}
	
	//static double last_dzat_x = 0.0;
	//static double last_dzat_y = 0.0;
	//static double last_dzat_z = 0.0;
	static char last_visible_sectors = 0;
	static Dword last_start_x = 0.0;
	static Dword last_start_y = 0.0;
	static Dword last_start_z = 0.0;
	Dword min_xy = 1E9;
	
	char visible_sectors = 9;
	if (field_amplificator) visible_sectors = 14;
	
	float starneg;
	
	if (!ap_targetting)
		starneg = 10000;
	else
		starneg = 1;

	Dword sect_x, sect_y, sect_z;
	Dword k = advance*visible_sectors;

	Dword temp_x, temp_y, temp_z;
	Word temp_rarity;

	Word rarity_factor;
	double distance_from_home;

	sect_x = (dzat_x - visible_sectors*halfadvance) / advance; sect_x *= advance;
	sect_y = (dzat_y - visible_sectors*halfadvance) / advance; sect_y *= advance;
	sect_z = (dzat_z - visible_sectors*halfadvance) / advance; sect_z *= advance;
	
	Dword start_x = sect_x;
	Dword start_y = sect_y;
	Dword start_z = sect_z;
	
	Udword initKeys[3];
	
	//Commented out lines in here are generally ones for the original star-generation algorithm (SL)
	if (last_visible_sectors==visible_sectors && start_x==last_start_x && start_y==last_start_y && start_z==last_start_z) {
		sect_x = start_x; sect_y = start_y; sect_z = start_z;
		for (Uword sx = visible_sectors; sx>0; sect_y=start_y, sect_x+=advance, sx--) {
			for (Uword sy = visible_sectors; sy>0; sect_z=start_z, sect_y+=advance, sy--) {
				for (Uword sz = visible_sectors; sz>0; sect_z+=advance, sz--) {
					StarData *sd = &last_stardata[sx-1][sy-1][sz-1];
					if (sd->HasStar()) {
						min_xy = plotStar(sd, starneg, limits, min_xy);
					}
				}
			}
		}
		
	} else {
		//index 0,0,0 of Last is 0,0,0
		//new sect is 1,1,1 more. index 0,0,0 of new is 1,1,1
		//sxAdjust = 1-0 = 1. nsx = 2 where sx=1.
		if (last_visible_sectors==visible_sectors) {
			sect_x = start_x; sect_y = start_y; sect_z = start_z;
			int sxAdjust = start_x - last_start_x;
			int syAdjust = start_y - last_start_y;
			int szAdjust = start_z - last_start_z;
			for (Uword sx = visible_sectors; sx>0; sect_y=start_y, sect_x+=advance, sx--) {
				Uword nsx = sx + sxAdjust;
				for (Uword sy = visible_sectors; sy>0; sect_z=start_z, sect_y+=advance, sy--) {
					Uword nsy = sy + syAdjust;
					for (Uword sz = visible_sectors; sz>0; sect_z+=advance, sz--) {
						Uword nsz = sz + szAdjust;
						if (nsx>0 && nsx<=visible_sectors && nsy>0 && nsy<=visible_sectors && nsz>0 && nsz<=visible_sectors) {
							last_stardata_new[sx-1][sy-1][sz-1].Copy(last_stardata[nsx-1][nsy-1][nsz-1]);
						} else {
							last_stardata_new[sx-1][sy-1][sz-1].Clear();
						}
					}
				}
			}
		} else {
			sect_x = start_x; sect_y = start_y; sect_z = start_z;
			for (Uword sx = visible_sectors; sx>0; sect_y=start_y, sect_x+=advance, sx--) {
				for (Uword sy = visible_sectors; sy>0; sect_z=start_z, sect_y+=advance, sy--) {
					for (Uword sz = visible_sectors; sz>0; sect_z+=advance, sz--) {
						last_stardata_new[sx-1][sy-1][sz-1].Clear();
					}
				}
			}
		}
		if (last_stardata == last_stardata0) {
			last_stardata = last_stardata1;
			last_stardata_new = last_stardata0;
		} else {
			last_stardata = last_stardata0;
			last_stardata_new = last_stardata1;
		}
		sect_x = start_x; sect_y = start_y; sect_z = start_z;
		for (Uword sx = visible_sectors; sx>0; sect_y=start_y, sect_x+=advance, sx--) {
			initKeys[0]=sect_x; //for the new galaxy (SL)
			DOUBLE_ dsect_x = sect_x; dsect_x*=dsect_x;
			for (Uword sy = visible_sectors; sy>0; sect_z=start_z, sect_y+=advance, sy--) {
				initKeys[1]=sect_y; //for the new galaxy (SL)
				DOUBLE_ dsect_y = sect_y; dsect_y=30*fabs(dsect_y);
				for (Uword sz = visible_sectors; sz>0; sect_z+=advance, sz--) {
					initKeys[2]=sect_z; //for the new galaxy (SL)
					StarData *sd = &last_stardata[sx-1][sy-1][sz-1];
					if (sd->HasStar()) {
						min_xy = plotStar(sd, starneg, limits, min_xy);
					} else if (!sd->IsInitialized()) {
						sd->NoStar();
						DOUBLE_ dsect_z = sect_z; dsect_z*=dsect_z;
						DOUBLE_ distance_from_home = SQRT (dsect_x + dsect_z) + dsect_y;
						rarity_factor = (Dword)(distance_from_home * 0.25e-8);
						rarity_factor = 1 << rarity_factor;
						rarity_factor--;
						init_by_array((unsigned long*)initKeys, 3); //for the new galaxy (SL)
						//xz = sect_x + sect_z;
						//temp_x = (xz & 0x1ffff) + sect_x - halfadvance;
						Word rarity = genrand_fast_int(0x7fff); //for the new galaxy (SL)
						if ((rarity & rarity_factor) == 0) {
							temp_x = genrand_fast_int(0x1ffff) + sect_x - halfadvance; //for the new galaxy (SL)
							if (temp_x!=0) {
								temp_y = genrand_fast_int(0x1ffff) + sect_y - halfadvance; //for the new galaxy (SL)
								//temp_y = ImulAndAdd(temp_x, xz);
								//mixer = xz + temp_y;
								//temp_y = (temp_y & 0x1ffff) + sect_y - halfadvance;
								if (temp_y!=0) {
									temp_z = genrand_fast_int(0x1ffff) + sect_z - halfadvance; //for the new galaxy (SL)
									//temp_z = ImulAndAdd(temp_y, mixer);
									//temp_z = (temp_z & 0x1ffff) + sect_z - halfadvance;
									if (temp_z!=0) {
										//Word rarity = (((Word)(temp_x)) + ((Word)(temp_y)) + ((Word)(temp_z)));
									
										double dlsx = (double) temp_x;
										double dlsy = (double) temp_y;
										double dlsz = (double) temp_z;
										double distFromHere = (dlsx-dzat_x)*(dlsx-dzat_x) + (dlsy-dzat_y)*(dlsy-dzat_y) + (dlsz-dzat_z)*(dlsz-dzat_z);
										double tempDxx = SQRT (dlsx * dlsx + dlsz * dlsz);
										tempDxx += fabs(dlsy * 30.0);
										if (tempDxx <= 2.0E9) {	//It's inside the galaxy
											//Set star record
											sd->x = temp_x;
											sd->y = temp_y;
											sd->z = temp_z;
											sd->sect_x = sect_x;
											sd->sect_y = sect_y;
											sd->sect_z = sect_z;
											
											//Star-rendering and targetting stuff
											min_xy = plotStar(sd, starneg, limits, min_xy);
										}
									}
								}
							}
						}
					}
				}
			}
		}
		last_visible_sectors = visible_sectors;
		last_start_x = start_x;
		last_start_y = start_y;
		last_start_z = start_z;
		
	}
	return True;
}

/*
old:
for (Uword sx = visible_sectors; sx>0; sect_y=start_y, sect_x+=advance, sx--) {
		initKeys[0]=sect_x; //for the new galaxy (SL)
		DOUBLE_ dsect_x = sect_x; dsect_x*=dsect_x;
		for (Uword sy = visible_sectors; sy>0; sect_z=start_z, sect_y+=advance, sy--) {
			initKeys[1]=sect_y; //for the new galaxy (SL)
			DOUBLE_ dsect_y = sect_y; dsect_y=30*fabs(dsect_y);
			for (Uword sz = visible_sectors; sz>0; sect_z+=advance, sz--) {
				initKeys[2]=sect_z; //for the new galaxy (SL)
				DOUBLE_ dsect_z = sect_z; dsect_z*=dsect_z;
				DOUBLE_ distance_from_home = SQRT (dsect_x + dsect_z) + dsect_y;
				rarity_factor = (Dword)(distance_from_home * 0.25e-8);
				rarity_factor = 1 << rarity_factor;
				rarity_factor--;
				init_by_array((unsigned long*)initKeys, 3); //for the new galaxy (SL)
				//xz = sect_x + sect_z;
				//temp_x = (xz & 0x1ffff) + sect_x - halfadvance;
				Word rarity = genrand_fast_int(0x7fff); //for the new galaxy (SL)
				if ((rarity & rarity_factor) == 0) {
					temp_x = genrand_fast_int(0x1ffff) + sect_x - halfadvance; //for the new galaxy (SL)
					if (temp_x!=0) {
						temp_y = genrand_fast_int(0x1ffff) + sect_y - halfadvance; //for the new galaxy (SL)
						//temp_y = ImulAndAdd(temp_x, xz);
						//mixer = xz + temp_y;
						//temp_y = (temp_y & 0x1ffff) + sect_y - halfadvance;
						if (temp_y!=0) {
							temp_z = genrand_fast_int(0x1ffff) + sect_z - halfadvance; //for the new galaxy (SL)
							//temp_z = ImulAndAdd(temp_y, mixer);
							//temp_z = (temp_z & 0x1ffff) + sect_z - halfadvance;
							if (temp_z!=0) {
								//Word rarity = (((Word)(temp_x)) + ((Word)(temp_y)) + ((Word)(temp_z)));
							
								double dlsx = (double) temp_x;
								double dlsy = (double) temp_y;
								double dlsz = (double) temp_z;
								double distFromHere = (dlsx-dzat_x)*(dlsx-dzat_x) + (dlsy-dzat_y)*(dlsy-dzat_y) + (dlsz-dzat_z)*(dlsz-dzat_z);
								double tempDxx = SQRT ((double)temp_x * (double)temp_x + (double)temp_z * (double)temp_z);
								tempDxx += fabs((double)temp_y * 30);
								if (tempDxx <= 2E9) {	//It's inside the galaxy
	*/

void CheckForAndPlaceGates() {
	Dword * nsid = (Dword*) (&nearstar_identity);
	Dword starSeed1 = *nsid;
	Dword starSeed2 = *(nsid+1);

		//fprintf(stderr, "starSeed1=0x%lx starSeed2=0x%lx ip_targetted=%li\n", starSeed1, starSeed2, (Dword)ip_targetted);
	if ((current_galaxy==0 && starSeed1==0x00000000 && starSeed2==0x4055a800) || (current_galaxy==1 && nearstar_sx==0 && nearstar_sy==0 && nearstar_sz==0)) {
		//Gate in new galaxy: nearstar_sx 0 nearstar_sy 0 nearstar_sz 0 nearstar_x -24649.000000 nearstar_y 14717.000000 nearstar_z -18469.000000 starSeed1=0x700084cc starSeed2=0x3f7b7140 ip_targetted=-1
		
		double key_radius;
		if (nearstar_nob==0) {
			nearstar_nop = 1;
			nearstar_nob = 1;
		}
		int n=0;
		nearstar_p_owner[n]	 = -1;
		nearstar_p_orb_orient[n] = (double) deg * (double) 90;
		nearstar_p_orb_seed[n]   = 3 * (n*n+1) * nearstar_ray + (float) (150 * nearstar_ray) / 100;
		nearstar_p_tilt[n]       = 0.0;
		nearstar_p_orb_tilt[n]   = 0.0;
		nearstar_p_orb_ecc[n]    = 0.5;
		nearstar_p_ray[n]        = (double) (nearstar_p_orb_seed[n]) * 0.0005 + 0.01;
		nearstar_p_ring[n]	 = (nearstar_p_ray[n]*.5) * (1 + (double) (500) / 100);
		nearstar_p_type[n] = planet_types+1;	//gateway
		
		key_radius = nearstar_ray * planet_orb_scaling;
		nearstar_p_ray[n] = avg_planet_ray[nearstar_p_type[n]]
			  + avg_planet_ray[nearstar_p_type[n]] * 50 / 200;
		nearstar_p_ray[n] *= avg_planet_sizing;
		nearstar_p_orb_ray[n] = key_radius + key_radius * 50 / 500;
		nearstar_p_orb_ray[n] += key_radius * avg_planet_ray[nearstar_p_type[n]];
		key_radius += nearstar_p_orb_ray[n];
		
		nearstar_labeled = 0;
		#ifdef OLD_STARMAP
		for (n = 1; n <= nearstar_nob; n++) {
			if (search_id_code (nearstar_identity + n, 'P') != -1)
				nearstar_labeled++;
		}
		#else
		Udword tgt_starFP = system_labelled(nearstar_sx, nearstar_sy, nearstar_sz, current_galaxy);
		/*for (n=0; n<nearstar_nob; n++) {
			//DebugPrintf(0, "N[%i] Clock: %li.", (int)n, clock());
			if (planet_labelled (tgt_starFP, n, nearstar_p_owner[n], nearstar_p_moonid[n], nearstar_p_type[n], False) != -1)
				nearstar_labeled++;
		}*/
		nearstar_labeled=planets_labelled(tgt_starFP, current_galaxy);
		#endif
		
		nearstar_p_rtperiod[n] = 0;
		
	} else if (current_galaxy==1) {
		fprintf(stderr, "nearstar_sx %i nearstar_sy %i nearstar_sz %i nearstar_x %f nearstar_y %f nearstar_z %f starSeed1=0x%lx starSeed2=0x%lx ip_targetted=%li\n", nearstar_sx, nearstar_sy, nearstar_sz, nearstar_x, nearstar_y, nearstar_z, starSeed1, starSeed2, (Dword)ip_targetted);
		
	}
}

void SwitchGalaxy() {
	current_galaxy = 1-current_galaxy;
	if (current_galaxy==0) {
		init_genrand(time(NULL));
		int destination = 7;
		while (destination>5) {
			destination = genrand_fast_int(0x7);
		}
		ap_targetting = 0;
		fprintf(stderr, "Teleporting to %i\n", destination);
		switch (destination) {
			case 0:
				ap_target_sx = -500000;
				ap_target_sy = -300000;
				ap_target_sz = 500000;
				ap_target_x = -550000;
				ap_target_y = -350000;
				ap_target_z = 450000;
				break;
			case 1:
				ap_target_sx = -500000;
				ap_target_sy = -300000;
				ap_target_sz = -500000;
				ap_target_x = 450000;
				ap_target_y = -350000;
				ap_target_z = -550000;
				break;
			case 2:
				ap_target_sx = 400000;
				ap_target_sy = -500000;
				ap_target_sz = 400000;
				ap_target_x = 350000;
				ap_target_y = -550000;
				ap_target_z = -450000;
				break;
			case 3:
				ap_target_sx = 100000;
				ap_target_sy = -11500000;
				ap_target_sz = 100000;
				ap_target_x = 50000;
				ap_target_y = -11550000;
				ap_target_z = -150000;
				break;
			case 4:
				ap_target_sx = -100000;
				ap_target_sy = -11500000;
				ap_target_sz = 100000;
				ap_target_x = -150000;
				ap_target_y = -11550000;
				ap_target_z = -150000;
				break;
			case 5:
				ap_target_sx = 0;
				ap_target_sy = 34700000;
				ap_target_sz = 0;
				ap_target_x = -50000;
				ap_target_y = 34650000;
				ap_target_z = -50000;
				break;
			
		}
	} else {
		ap_target_sx = 0;
		ap_target_sy = 0;
		ap_target_sz = 0;
		ap_target_x = -24649;
		ap_target_y = 14717;
		ap_target_z = -18469;
	}
	vimana_shield = 3;
	dzat_x = ap_target_sx;
	dzat_y = ap_target_sy;
	dzat_z = ap_target_sz;
	landing_point = 0;
	ap_targetting = 1;
	extract_ap_target_infos ();
	fix_remote_target ();
	ap_targetting = 0;
	stspeed = 1; // partenza automatica
	if (ap_targetted) {
		nsnp = 1;
		ap_reached = 0;
		ip_reached = 0;
		ip_targetted = -1;
	}
}

int ConvertCommand(char* originalCommand, char* output) {
	for (int i=0; i<num_command_conversions; i++) {
		fprintf(stderr, "Comparing (%s) to (%s)\n", originalCommand, command_conversions_from[i]);
		if (command_conversions_from[i]!=NULL && strncmpi(command_conversions_from[i], originalCommand, strlen(command_conversions_from[i]))==0) {
			fprintf(stderr, "Changing it to (%s)\n", command_conversions_to[i]);
			sprintf(output, "%s %s", command_conversions_to[i], originalCommand+strlen(command_conversions_from[i]));
			return 1;
		}
	}
	return 0;
}

void NgInit() {
	if (last_stardata0 == NULL) {
		last_stardata0 = new (StarData**)[14];
		last_stardata1 = new (StarData**)[14];
		for (int i=0; i<14; i++) {
			last_stardata0[i] = new (StarData*)[14];
			last_stardata1[i] = new (StarData*)[14];
			for (int j=0; j<14; j++) {
				last_stardata0[i][j] = new StarData[14];
				last_stardata1[i][j] = new StarData[14];
			}
		}
		last_stardata = last_stardata0;
		last_stardata_new = last_stardata1;
	}
	
	command_conversions_from = NULL;
	command_conversions_to = NULL;
	char *temp = new char[128];
	FILE * convFile = fopen("..\\wmodulesalias.txt", "rt");
	if (convFile==NULL) {
		num_command_conversions = 0;
		fprintf(stderr, "Unable to read wmodulesalias.txt.\n");
	} else {
		int numLines = CountLines(convFile);
		num_command_conversions=0;
		command_conversions_from = new (char*)[numLines];
		command_conversions_to = new (char*)[numLines];
		for (int i=0; i<numLines; i++) {
			ReadLine(convFile, temp, 128);
			char *splitPos = strstr(temp, " -> ");
			if (splitPos!=NULL) {
				char *oconvFrom = temp;
				splitPos[1]=0;
				char *oconvTo = (splitPos+4);
				char *convFrom = new char[strlen(oconvFrom)];
				char *convTo = new char[strlen(oconvTo)];
				strcpy(convFrom, oconvFrom);
				strcpy(convTo, oconvTo);
				splitPos[1]=' ';
				fprintf(stderr, "Read line (%s), convert (%s) to (%s).\n", temp, convFrom, convTo);
				command_conversions_from[num_command_conversions] = convFrom;
				command_conversions_to[num_command_conversions] = convTo;
				num_command_conversions+=1;
			}
		}
		fclose(convFile);
		delete [] temp;
	}
}

void NgCleanup() {
	for (int i=0; i<14; i++) {
		for (int j=0; j<14; j++) {
			delete [] last_stardata0[i][j];
			delete [] last_stardata1[i][j];
			last_stardata0[i][j] = NULL;
			last_stardata1[i][j] = NULL;
		}
		delete [] last_stardata0[i];
		delete [] last_stardata1[i];
		last_stardata0[i] = NULL;
		last_stardata1[i] = NULL;
	}
	delete [] last_stardata0;
	delete [] last_stardata1;
	last_stardata0 = NULL;
	last_stardata1 = NULL;
	last_stardata = NULL;
	last_stardata_new = NULL;
	
	for (int i=0; i<num_command_conversions; i++) {
		delete [] command_conversions_from[i];
		delete [] command_conversions_to[i];
	}
	delete [] command_conversions_from;
	delete [] command_conversions_to;
	num_command_conversions=0;
}

#endif