/*

	Noctis galactic guide / SL command.
	GOES Net Module.

	Modified Apr 22 2005 by SL: Updated for starmap3.
	Changed to use modshare Feb 20 2005 by SL.
	Modified Feb 13 2005 by SL to fix possible bug due to use of align_m and align_e, now uses start_y and start_z instead.
	I haven't unified this yet with modshare.hpp.
	
	
*/

#include <stdlib.h>
#include <string.h>
#include <stdio.h>
#include <conio.h>
#include <math.h>
#include <dos.h>
#include <io.h>
#include "modshare.hpp"

//////////////////////////////////////////////////////////////////////////////

//char   *situation_file  = "..\\DATA\\Current.BIN";

char   sync               = 1;		// 0
char   anti_rad           = 1;          // 1
char   pl_search          = 0;          // 2
char   field_amplificator = 0;          // 3
char   ilight             = 63;         // 4
char   ilightv            = 1;          // 5
char   charge             = 3;          // 6
char   revcontrols        = 0;          // 7
char   ap_targetting      = 0;          // 8
char   ap_targetted       = 0;          // 9
char   ip_targetting      = 0;          // 10
char   ip_targetted       = -1;		// 11
char   ip_reaching        = 0;          // 12
char   ip_reached         = 0;          // 13
char   ap_target_spin     = 0;          // 14
char   ap_target_r        = 0;          // 15
char   ap_target_g        = 0;          // 16
char   ap_target_b        = 0;          // 17
char   nearstar_spin      = 0;          // 18
char   nearstar_r         = 0;          // 19
char   nearstar_g         = 0;          // 20
char   nearstar_b         = 0;          // 21
char   gburst	          = 0;          // 22
char   menusalwayson      = 1;		// 23
char   depolarize  	  = 0;          // 24
int    sys                = 4;		// 25
int    pwr                = 15000;	// 27
int    dev_page           = 0;		// 29
int    ap_target_class    = 0;		// 31
int    f_ray_elapsed	  = 0;		// 33
int    nearstar_class     = 0;		// 35
int    nearstar_nop       = 0;		// 37
float  pos_x              = 0;		// 39
float  pos_y              = 0;		// 43
float  pos_z              = -500;	// 47
float  user_alfa          = 0;		// 51
float  user_beta          = 0;		// 55
float  navigation_beta    = 0;		// 59
float  ap_target_ray      = 0;		// 63
float  nearstar_ray       = 1000;	// 67
double dzat_x             = +3797120;
double dzat_y             = -4352112;
double dzat_z             = -925018;
double ap_target_x        = 0;
double ap_target_y        = 1E9;
double ap_target_z        = 0;
double nearstar_x         = 0;
double nearstar_y         = 1E9;
double nearstar_z         = 0;
double helptime           = 0;
double ip_target_initial_d= 0;
double requested_approach_coefficient = 1;
double current_approach_coefficient = 1;
double reaction_time      = 0.01;
char   fcs_status[11]     = "STANDBY";
int    fcs_status_delay   = 0;
int    psys               = 4;
double ap_target_initial_d= 0;
double requested_vimana_coefficient = 1;
double current_vimana_coefficient = 1;
double vimana_reaction_time = 0.01;
char   lithium_collector  = 0;
char   autoscreenoff	  = 0;
char   ap_reached         = 0;
int    lifter		  = 0;
double secs		  = 0;

void unfreeze ()
{
	FILE * fh = fopen (real_situation_file, "rb");
	if (fh!=NULL) {
		fread (&sync, 244, 1, fh);
		fclose (fh);
	}
}


double 	object_id = 12345;
char   	object_label[25];
double 	s_object_id = 12345;
char   	s_object_label[25];

double	subject_id = 12345;
double  idscale = 0.00001;

int	sts;
char	query;

long	round;
int 	i;
FILE * fh, gh;
int 	analyzed_sectors_range;
char	*file = "..\\DATA\\starmap3.map";
char	*guide = "..\\DATA\\starmap3.gd";

char	outbuffer[40];
char	textbuffer[40];
char	parbuffer[160];
char	nullbuffer[128];
char	objectname[21];
char	subjectname[21];

double	mblock_subject;
char	mblock_message[77];

//////////////////////////////////////////////////////////////////////////////

double laststar_x, laststar_y, laststar_z;

/*char isthere (double star_id)
{
	char warnbuffer[41];

	double laststar_id;

	double sidlow = star_id - idscale;
	double sidhigh = star_id + idscale;

	unsigned sx, sy, sz;

	unsigned visible_sectors_x = analyzed_sectors_range;
	unsigned visible_sectors_y = analyzed_sectors_range;
	unsigned visible_sectors_z = analyzed_sectors_range;

	long   	advance = 100000;
	long   	sect_x, sect_y, sect_z;

	sect_x = (dzat_x - visible_sectors_x*50000) / 100000; sect_x *= 100000;
	sect_y = (dzat_y - visible_sectors_y*50000) / 100000; sect_y *= 100000;
	sect_z = (dzat_z - visible_sectors_z*50000) / 100000; sect_z *= 100000;

	long start_y = sect_y;
	long start_z = sect_z;
	
	asm {	mov ax, visible_sectors_x
		mov sx, ax }
e_while:asm {	mov ax, visible_sectors_y
		mov sy, ax }
m_while:asm {	mov ax, visible_sectors_z
		mov sz, ax }
i_while:asm {	db 0x66, 0xBB, 0x50, 0xC3, 0x00, 0x00 // mov ebx, 50000
		db 0x66; mov ax, word ptr sect_x
		db 0x66; mov dx, word ptr sect_z
		db 0x66; add ax, dx
		db 0x66; mov cx, ax
		db 0x66; mov dx, ax
		db 0x66, 0x81, 0xE2, 0xFF, 0xFF, 0x01, 0x00 // and edx, 0x0001FFFF
		db 0x66; add dx, word ptr sect_x
		db 0x66; sub dx, bx
		db 0x66; mov word ptr laststar_x, dx
		db 0x66; imul dx
		db 0x66; add dx, ax
		db 0x66; add cx, dx
		db 0x66, 0x81, 0xE2, 0xFF, 0xFF, 0x01, 0x00 // and edx, 0x0001FFFF
		db 0x66; add dx, word ptr sect_y
		db 0x66; sub dx, bx
		db 0x66; mov word ptr laststar_y, dx
		db 0x66; mov ax, cx
		db 0x66; imul dx
		db 0x66; add dx, ax
		db 0x66, 0x81, 0xE2, 0xFF, 0xFF, 0x01, 0x00 // and edx, 0x0001FFFF
		db 0x66; add dx, word ptr sect_z
		db 0x66; sub dx, bx
		db 0x66; mov word ptr laststar_z, dx
		fild dword ptr laststar_x
		fst  laststar_x
		fmul idscale
		fild dword ptr laststar_y
		fst  laststar_y
		fmul idscale
		fild dword ptr laststar_z
		fst  laststar_z
		fmul idscale
		fmulp
		fmulp
		fst laststar_id
		fcomp sidlow
		fstsw ax
		sahf
		jb i_next
		fld laststar_id
		fcomp sidhigh
		fstsw ax
		sahf
		jb y_end }
i_next:	asm {	db 0x66; mov ax, word ptr advance
		db 0x66; add word ptr sect_z, ax
		dec sz
		jz i_end
		jmp i_while }
i_end:	  asm { db 0x66; mov dx, word ptr start_z
		db 0x66; mov word ptr sect_z, dx
		db 0x66; add word ptr sect_y, ax
		dec sy
		jz m_end
		jmp m_while }
y_end:	  return (1);
m_end:	  asm { db 0x66; mov dx, word ptr start_y
		db 0x66; mov word ptr sect_y, dx
		db 0x66; add word ptr sect_x, ax
		dec sx
		jz e_end
		db 0x66; pusha }
		sprintf (warnbuffer, "SLICE %d OF %d", visible_sectors_x - sx, visible_sectors_x);
		warn (warnbuffer, 0);
		sprintf (warnbuffer, "SUBJECT %ld OF %ld", current_star, total_stars);
		warn (warnbuffer, 1);
		while (kbhit()) {
			if (getch() == 27) {
				asm { db 0x66; popa }
				return (2);
			}
		}
	  asm { db 0x66; popa
		jmp e_while }
e_end:	  return (0);
}*/

//////////////////////////////////////////////////////////////////////////////

Uchar flags;
Udword discoverer;
char name[21];
char lastname[21];
Dword sx, sy, sz;
Uword data;
Udword nextAlternateFP;
Udword starFP;
Bool exactMatch = 0;

void liststars (Udword starmap3Len)
{
	char	least = 0, retval;
	double	xdist, ydist, zdist, dist;
	double coorddist = analyzed_sectors_range*advance;
	
	fseek (fh, 10, SEEK_SET);
	while (ftell(fh)<starmap3Len) {
		fread(&flags, 1, 1, fh);
		fread(&discoverer, 4, 1, fh);
		fread(&name, 20, 1, fh);
		if (flags&0x8) {
			fread(&sx, 4, 1, fh);
			fread(&sy, 4, 1, fh);
			fread(&sz, 4, 1, fh);
			fread(&data, 2, 1, fh);
			fread(&nextAlternateFP, 4, 1, fh);
			if (!(flags&0x20)) {
				least=1;
				if (sts) {
					//get coords, check them
					PrepareFromSectorCoords(sx, sy, sz);
					xdist = dzat_x - foundstar_x;
					ydist = dzat_y - foundstar_y;
					zdist = dzat_z - foundstar_z;
					dist = sqrt(xdist*xdist+ydist*ydist+zdist*zdist);
					if (dist<=coorddist) {
						sprintf (textbuffer, "*%.20s", name);
						msg (textbuffer);
						sprintf (textbuffer, "$X=%1.0f", foundstar_x);
						msg (textbuffer);
						sprintf (textbuffer, "$Y=%1.0f", -foundstar_y);
						msg (textbuffer);
						sprintf (textbuffer, "$Z=%1.0f", foundstar_z);
						msg (textbuffer);
						sprintf (textbuffer, "$D=%1.2f L.Y.", dist * 5E-5);
						msg (textbuffer);
						msg ("[&&&&&&&&&&&&&&&&&&&&");
					}
				} else {
					sprintf (textbuffer, "*%.20s", name);
					msg (textbuffer);
				}
			}
		} else {
			fread(&starFP, 4, 1, fh);
			fread(&data, 2, 1, fh);
			fread(&nextAlternateFP, 4, 1, fh);
		}
	}
	//----
	/*
	while (_read (fh, &object_id, 8) && _read (fh, &object_label, 24) == 24) {
		if (memcmp (&object_id, "Removed:", 8) && object_label[21] == 'S') {
			least = 1;
			if (sts) {
				current_star++;
				retval = isthere2 (object_id, analyzed_sectors_range, dzat_x, dzat_y, dzat_z, 1);
				if (retval == 2) {
					msg (divider);
					msg ("INTERRUPTED!");
					return;
				}
				if (retval) {
					sprintf (textbuffer, "*%s", object_label);
					msg (textbuffer);
					sprintf (textbuffer, "$X=%1.0f", laststar_x);
					msg (textbuffer);
					sprintf (textbuffer, "$Y=%1.0f", -laststar_y);
					msg (textbuffer);
					sprintf (textbuffer, "$Z=%1.0f", laststar_z);
					msg (textbuffer);
					xdist = dzat_x - laststar_x;
					ydist = dzat_y - laststar_y;
					zdist = dzat_z - laststar_z;
					dist = sqrt(xdist*xdist+ydist*ydist+zdist*zdist);
					sprintf (textbuffer, "$D=%1.2f L.Y.", dist * 5E-5);
					msg (textbuffer);
					msg ("[&&&&&&&&&&&&&&&&&&&&");
				}
			}
			else {
				sprintf (textbuffer, "*%s", object_label);
				msg (textbuffer);
			}
		}
	}*/

	if (least) {
		msg (divider);
		msg ("STARS LISTING END.");
	}
	else
		msg ("NO KNOWN STARS.");
}

void main ()
{
	CHECK_SITUATION;
	/*asm {	xor	ax, ax
		mov	es, ax
		cmp	byte ptr es:[0x449], 0x13
		je	startup }

	printf ("\nGalactic Organization of Explorers and Stardrifters (G.O.E.S)\n");
	printf ("-------------------------------------------------------------\n");
	printf ("This is a GOES NET module and must be run from a stardrifter.\n");
	printf ("Please use the onboard computer console to run this module.\n");
	printf ("\n\t- GOES NET onboard microsystem, EPOC 6011 REVISION 2\n");
	return;*/

	//startup:
	msg ("________USAGE________");
	msg ("SL (OPTIONAL RANGE)");
	msg ("^^^^^^^^^^^^^^^^^^^^^");

	if (_argc < 2)
		msg ("GLOBAL STARS LISTING:");
	else
		msg ("RANGED STARS LISTING:");

	msg (divider);
	#ifdef GALAXY2
	ReadCurrentGalaxy();
	if (current_galaxy==1) {
		file=file2;
		guide=guide2;
	}
	#endif
	
	fh = fopen (file, "rb");
	if (fh == NULL) {
		msg ("STARMAP NOT AVAILABLE");
		return;
	}
	Udword starmap3Len = 0;
	fseek(fh, 0, SEEK_END);
	starmap3Len = ftell(fh);
	fseek(fh, 0, SEEK_SET);
	Uword fileFormatVersion;
	Udword starmap3VersionHalf;
	fread(&fileFormatVersion, 2, 1, fh);
	fread(&starmap3VersionHalf, 4, 1, fh);
	fread(&starmap3VersionHalf, 4, 1, fh);
	
	i = 2;
	strcpy (parbuffer, _argv[1]);
	while (i < _argc) {
		strcat (parbuffer, " ");
		strcat (parbuffer, _argv[i]);
		i++;
	}

	i = 0;
	while (parbuffer[i]) {
		if (parbuffer[i] == '_')
			parbuffer[i] = 32;
		i++;
	}

	if (_argc > 1) {
		sts = atoi (parbuffer);
		if (sts <= 2 || sts > 10000)
			analyzed_sectors_range = 100;
		else
			analyzed_sectors_range = sts;
		unfreeze ();
		//current_star = 0;
		//while (_read (fh, &object_id, 8) && _read (fh, &object_label, 24) == 24) {
		//	if (memcmp (&object_id, "Removed:", 8) && object_label[21] == 'S')
		//		total_stars++;
		//}
	}
	else
		sts = 0;
	liststars (starmap3Len);

	fclose (fh);
	
}