Browse Source

0.100 Alpha

dev
surkhe 6 months ago
commit
974598c4fa
  1. 46
      FileWindow.cpp
  2. 25
      FileWindow.h
  3. 163
      GBCSolution.cpp
  4. 73
      GBCSolution.h
  5. 42
      GNU_Ballistics.cpp
  6. 515
      InputWindow.cpp
  7. 110
      InputWindow.h
  8. 4
      Makefile
  9. 662
      RangeWindow.cpp
  10. 63
      RangeWindow.h
  11. 20
      _angle.c
  12. 38
      _atmosphere.c
  13. 116
      _retard.c
  14. 73
      _retrieve.c
  15. 70
      _solve.c
  16. 19
      _windage.c
  17. 78
      _zero.c
  18. 173
      ballistics.h
  19. 46
      example.c

46
FileWindow.cpp

@ -0,0 +1,46 @@ @@ -0,0 +1,46 @@
FileWindow::FileWindow(int w, int h, const char* title, char** fName) : Fl_Window(w,h,title){
this->complete=0;
this->set_modal();
char cwd[1024];
getcwd(cwd,1024);
FN = fName;
begin();
iFile = new Fl_File_Input(30,50,150,35,"File Name");
iFile->value(cwd);
btOK = new Fl_Button(w-55,h-35,50,30,"OK");
btOK->callback(cb_bt_OK,this);
show();
end();
}
FileWindow::~FileWindow(){
complete=1;
}
void FileWindow::cb_bt_OK(Fl_Widget* fw, void* t){
FileWindow* T = (FileWindow*)t;
T->fw_exit();
}
void FileWindow::fw_exit(){
char* k = (char*)malloc(sizeof(char)*strlen(iFile->value()));
strcpy(k,iFile->value());
printf("\nLOCATION 1: %s",k);
*FN = k;
this->~FileWindow();
}

25
FileWindow.h

@ -0,0 +1,25 @@ @@ -0,0 +1,25 @@
#ifndef _FILEWINDOW_H_
#define _FILEWINDOW_H_
#include <unistd.h>
class FileWindow : public Fl_Window{
public:
FileWindow(int w, int h, const char* title, char** fName);
~FileWindow();
int complete;
private:
char** FN;
Fl_Button* btOK;
Fl_File_Input* iFile;
static void cb_bt_OK(Fl_Widget*, void*);
void fw_exit(void);
};
#include "FileWindow.cpp"
#endif

163
GBCSolution.cpp

@ -0,0 +1,163 @@ @@ -0,0 +1,163 @@
GBCSolution::GBCSolution(void){
}
GBCSolution::GBCSolution(double* isolution, const char* iname, double ibc, double isightheight, int iweight, int imv, int iangle, int izerorange, int iwindspeed, int iwindangle, int itemp, int ihumidity, double ipressure, int ialtitude, int entries){
sln=isolution;
strcpy(name,iname);
bc=ibc;
sightheight=isightheight;
weight=iweight;
mv=imv;
angle=iangle;
zerorange=izerorange;
windspeed=iwindspeed;
windangle=iwindangle;
temp=itemp;
humidity=ihumidity;
pressure=ipressure;
altitude=ialtitude;
rows=entries;
}
GBCSolution::~GBCSolution(){
}
const char* GBCSolution::Name(void){
return name;
}
double GBCSolution::BC(void){
return bc;
}
double GBCSolution::SightHeight(void){
return sightheight;
}
int GBCSolution::MuzzleVelocity(void){
return mv;
}
int GBCSolution::ShootingAngle(void){
return angle;
}
int GBCSolution::ZeroRange(void){
return zerorange;
}
int GBCSolution::WindSpeed(void){
return windspeed;
}
int GBCSolution::WindAngle(void){
return windangle;
}
int GBCSolution::Temp(void){
return temp;
}
double GBCSolution::Pressure(void){
return pressure;
}
int GBCSolution::Humidity(void){
return humidity;
}
int GBCSolution::Altitude(void){
return altitude;
}
double GBCSolution::GetRange(int yardage){
double size=sln[__BCOMP_MAXRANGE__*10+1];
if (yardage<size){
return sln[10*yardage];
}
else return 0;
}
double GBCSolution::GetPath(int yardage){
double size=sln[__BCOMP_MAXRANGE__*10+1];
if (yardage<size){
return sln[10*yardage+1];
}
else return 0;
}
double GBCSolution::GetMOA(int yardage){
double size=sln[__BCOMP_MAXRANGE__*10+1];
if (yardage<size){
return sln[10*yardage+2];
}
else return 0;
}
double GBCSolution::GetTime(int yardage){
double size=sln[__BCOMP_MAXRANGE__*10+1];
if (yardage<size){
return sln[10*yardage+3];
}
else return 0;
}
double GBCSolution::GetWindage(int yardage){
double size=sln[__BCOMP_MAXRANGE__*10+1];
if (yardage<size){
return sln[10*yardage+4];
}
else return 0;
}
double GBCSolution::GetWindageMOA(int yardage){
double size=sln[__BCOMP_MAXRANGE__*10+1];
if (yardage<size){
return sln[10*yardage+5];
}
else return 0;
}
double GBCSolution::GetVelocity(int yardage){
double size=sln[__BCOMP_MAXRANGE__*10+1];
if (yardage<size){
return sln[10*yardage+6];
}
else return 0;
}
double GBCSolution::GetVx(int yardage){
double size=sln[__BCOMP_MAXRANGE__*10+1];
if (yardage<size){
return sln[10*yardage+7];
}
else return 0;
}
double GBCSolution::GetVy(int yardage){
double size=sln[__BCOMP_MAXRANGE__*10+1];
if (yardage<size){
return sln[10*yardage+8];
}
else return 0;
}
int GBCSolution::MaxRows(void){
return rows;
}
int GBCSolution::Weight(void){
return weight;
}

73
GBCSolution.h

@ -0,0 +1,73 @@ @@ -0,0 +1,73 @@
class GBCSolution {
public:
GBCSolution(void);
GBCSolution(
double* isolution,
const char* name,
double ibc,
double isightheight,
int iweight,
int imv,
int iangle,
int izerorange,
int iwindspeed,
int iwindangle,
int itemp,
int ihumidity,
double ipressure,
int ialtitude,
int rows
);
~GBCSolution();
double* sln;
const char* Name(void);
double BC(void);
double SightHeight(void);
int MuzzleVelocity(void);
int ShootingAngle(void);
int ZeroRange(void);
int WindSpeed(void);
int WindAngle(void);
int Temp(void);
double Pressure(void);
int Humidity(void);
int Altitude(void);
int Weight(void);
int MaxRows(void);
double GetRange(int yardage);
double GetPath(int yardage);
double GetMOA(int yardage);
double GetTime(int yardage);
double GetWindage(int yardage);
double GetWindageMOA(int yardage);
double GetVelocity(int yardage);
double GetVx(int yardage);
double GetVy(int yardage);
private:
double* solution;
char name[1024];
int weight;
double bc;
double sightheight;
int mv;
int angle;
int zerorange;
int windspeed;
int windangle;
int temp;
double pressure;
int humidity;
int altitude;
int rows;
};

42
GNU_Ballistics.cpp

@ -0,0 +1,42 @@ @@ -0,0 +1,42 @@
#include <FL/Fl.H>
#include <FL/Fl_Window.H>
#include <FL/Fl_Button.H>
#include <FL/Fl_Input.H>
#include <FL/Fl_Output.H>
#include <FL/Fl_Menu_Bar.H>
#include <FL/Fl_Menu_Item.H>
#include <FL/Fl_Round_Button.H>
#include <FL/Fl_Box.H>
#include <FL/Fl_Check_Button.H>
#include <FL/Fl_Int_Input.H>
#include <FL/Fl_Float_Input.H>
#include <FL/Fl_Multiline_Output.H>
#include <FL/Fl_BMP_Image.H>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include "GBCSolution.h"
#include "ballistics.h"
#include "InputWindow.h"
#include "RangeWindow.h"
#include "InputWindow.cpp"
#include "RangeWindow.cpp"
#include "GBCSolution.cpp"
using namespace std;
void InitMenu(InputWindow*);
int main (){
InputWindow win(400,500,"GNU Exterior Ballistics Computer");
return Fl::run();
}

515
InputWindow.cpp

@ -0,0 +1,515 @@ @@ -0,0 +1,515 @@
InputWindow::InputWindow(int w, int h, const char* title):Fl_Window(w,h,title){
begin();
Solution=NULL;
// Draw any general purpose borders or labels.
Fl_Box* GBox = new Fl_Box(250,80,140,95,"Drag Function");
GBox->box(FL_BORDER_BOX);
GBox->align(FL_ALIGN_LEFT | FL_ALIGN_TOP | FL_ALIGN_INSIDE);
// Create and place the Drag Function inputs on the form.
inG1 = new Fl_Round_Button(270,105,30,15,"G1");
inG2 = new Fl_Round_Button(270,125,30,15,"G2");
inG5 = new Fl_Round_Button(270,145,30,15,"G5");
inG6 = new Fl_Round_Button(330,105,30,15,"G6");
inG7 = new Fl_Round_Button(330,125,30,15,"G7");
inG8 = new Fl_Round_Button(330,145,30,15,"G8");
inG1->type(FL_RADIO_BUTTON);
inG2->type(FL_RADIO_BUTTON);
inG5->type(FL_RADIO_BUTTON);
inG6->type(FL_RADIO_BUTTON);
inG7->type(FL_RADIO_BUTTON);
inG8->type(FL_RADIO_BUTTON);
inG1->set();
// Create and place the input fields on the form.
inName = new Fl_Input(55,45,335,20,"Name ");
inBC = new Fl_Float_Input(10,80,50,20," Drag Coefficient");
inWeight=new Fl_Int_Input(10,105,50,20," Projectile Weight (grains)");
inMV = new Fl_Int_Input(10,130,50,20," Initial Velocity (ft/s)");
inZero = new Fl_Int_Input(10,155,50,20," Zero Range (yds)");
inSH = new Fl_Float_Input(10,180,50,20," Sight Height Over Bore (in)");
inAngle = new Fl_Int_Input(10,205,50,20," Shooting Angle (deg)");
inVwind = new Fl_Int_Input(10,230,50,20," Wind Velocity (mi/hr)");
inAwind = new Fl_Int_Input(10,255,50,20," Wind Angle (0-360 deg)");
inName->align(FL_ALIGN_LEFT);
inBC->align(FL_ALIGN_RIGHT);
inWeight->align(FL_ALIGN_RIGHT);
inMV->align(FL_ALIGN_RIGHT);
inZero->align(FL_ALIGN_RIGHT);
inAngle->align(FL_ALIGN_RIGHT);
inVwind->align(FL_ALIGN_RIGHT);
inAwind->align(FL_ALIGN_RIGHT);
inSH->align(FL_ALIGN_RIGHT);
inName->value("308 Win Match, 168gr Sierra Match King");
inBC->value("0.465");
inWeight->value("168");
inMV->value("2650");
inZero->value("200");
inAngle->value("0");
inVwind->value("0");
inAwind->value("0");
inSH->value("1.6");
// Put a checkbox to enable atmospheric corrections.
ckWeather = new Fl_Check_Button(10,290,20,20,"Enable Atmospheric Corrections");
ckWeather->align(FL_ALIGN_RIGHT);
ckWeather->callback(cb_ckWeather,this);
// Now the atmospheric inputs.
inAltitude = new Fl_Int_Input(10,315,50,20," Altitude (ft)");
inTemp = new Fl_Int_Input(10,340,50,20," Temperature (F)");
inPressure = new Fl_Float_Input(10,365,50,20," Barometric Pressure (in Hg)");
inHumidity = new Fl_Int_Input(10,390,50,20," Relative Humidity (%)");
inTemp->align(FL_ALIGN_RIGHT);
inPressure->align(FL_ALIGN_RIGHT);
inAltitude->align(FL_ALIGN_RIGHT);
inHumidity->align(FL_ALIGN_RIGHT);
inTemp->value("59");
inAltitude->value("0");
inPressure->value("29.53");
inHumidity->value("78");
// Disable the atmospheric conditions at first.
ckWeather->activate();
inTemp->deactivate();
inAltitude->deactivate();
inPressure->deactivate();
inHumidity->deactivate();
oStatus = new Fl_Multiline_Output(10,420,380,70,"Solution Status");
oStatus->align(FL_ALIGN_LEFT | FL_ALIGN_TOP | FL_ALIGN_INSIDE);
oStatus->value("GNU Ballistic Computer: Waiting for Input");
// Create and place buttons on the form.
btSolve = new Fl_Button( 340, 380, 50, 30, "So&lve");
btReset = new Fl_Button( 280, 380, 50, 30, "&Reset");
btSolve->callback(cb_Solve,this);
btReset->callback(cb_Clear, this);
// Declare the menu bar variables
// m for menu, mc for menu choice.
menu = new Fl_Menu_Bar(0,0,400,30, "MENU");
Fl_Menu_Item m_File = {"&File",0,0,0,FL_SUBMENU};
Fl_Menu_Item mc_New = {"&New...",0,(Fl_Callback*)cb_mNew,this};
Fl_Menu_Item mc_Open = {"&Open...",0,(Fl_Callback*)cb_mOpen,this};
Fl_Menu_Item mc_Save = {"&Save...",0,(Fl_Callback*)cb_Nothing};
Fl_Menu_Item mc_Export = {"&Export Data...",0,(Fl_Callback*)cb_Nothing};
Fl_Menu_Item mc_Quit = {"&Quit",0,(Fl_Callback*)cb_Quit};
Fl_Menu_Item m_Edit = {"&Edit",0,0,0, FL_SUBMENU};
Fl_Menu_Item mc_Copy = {"&Copy",0,(Fl_Callback*)cb_Copy,this};
Fl_Menu_Item mc_Paste = {"&Paste",0,(Fl_Callback*)cb_Paste,this};
Fl_Menu_Item mc_Options = {"&Options",0,(Fl_Callback*)cb_Nothing};
Fl_Menu_Item m_Analyze = {"&Analyze",0,0,0, FL_SUBMENU};
Fl_Menu_Item mc_Table = {"&Range Table",0,(Fl_Callback*)cb_RangeTable,this};
Fl_Menu_Item mc_Plot = {"&Plot...",0,(Fl_Callback*)cb_Nothing};
Fl_Menu_Item mc_Compare = {"&Compare...",0,(Fl_Callback*)cb_Nothing};
Fl_Menu_Item m_Aids = {"Shooting &Aids",0,0,0, FL_SUBMENU};
Fl_Menu_Item mc_RangeCard = {"&Range Card",0,(Fl_Callback*)cb_Nothing};
Fl_Menu_Item mc_ClickChart = {"&Click Chart",0,(Fl_Callback*)cb_Nothing};
Fl_Menu_Item mc_RangeTable = {"&Range Table",0,(Fl_Callback*)cb_Nothing};
Fl_Menu_Item m_Solution = {"&Analysis",0,0,0, FL_SUBMENU};
Fl_Menu_Item mc_Solve = {"&Solve",0,(Fl_Callback*)cb_Solve,this};
Fl_Menu_Item mc_Advanced = {"&Advanced Settings",0,(Fl_Callback*)cb_Nothing};
Fl_Menu_Item m_Help = {"&Help",0,0,0, FL_SUBMENU};
Fl_Menu_Item mc_Help = {"&Online Help",0,(Fl_Callback*)cb_Nothing};
Fl_Menu_Item mc_License = {"&License",0,(Fl_Callback*)cb_Nothing};
Fl_Menu_Item mc_About = {"&About",0,(Fl_Callback*)cb_Nothing};
Fl_Menu_Item mc_Bug = {"&Bug Report",0,(Fl_Callback*)cb_Nothing};
Fl_Menu_Item m_Tools = {"&Tools",0,0,0, FL_SUBMENU};
Fl_Menu_Item mc_OptimizePBR = {"&Optimize PBR",0,(Fl_Callback*)cb_Nothing};
Fl_Menu_Item mc_CalcBC = {"&Calculate Drag Coefficient",0,(Fl_Callback*)cb_Nothing};
Fl_Menu_Item m_Compare = {"&Compare",0,0,0, FL_SUBMENU};
Fl_Menu_Item mc_Store1 = {"Store Solution 1",0,(Fl_Callback*)cb_Nothing};
Fl_Menu_Item mc_Store2 = {"Store Solution 2",0,(Fl_Callback*)cb_Nothing};
Fl_Menu_Item mc_Store3 = {"Store Solution 3",0,(Fl_Callback*)cb_Nothing};
Fl_Menu_Item mc_Store4 = {"Store Solution 4",0,(Fl_Callback*)cb_Nothing};
Fl_Menu_Item mc_Store5 = {"Store Solution 5",0,(Fl_Callback*)cb_Nothing,0,FL_MENU_DIVIDER};
Fl_Menu_Item mc_CompareTable = {"Table",0,0,0,FL_SUBMENU};
Fl_Menu_Item mc_CompareDrop = {"Drop Table",0,(Fl_Callback*)cb_Nothing};
Fl_Menu_Item mc_CompareVelocity = {"Velocity Table",0,(Fl_Callback*)cb_Nothing};
Fl_Menu_Item mc_CompareEnergy = {"Energy Table",0,(Fl_Callback*)cb_Nothing};
Fl_Menu_Item mc_CompareWind = {"Windage Table",0,(Fl_Callback*)cb_Nothing};
Fl_Menu_Item mc_ComparePlot = {"Plot",0,0,0,FL_SUBMENU};
Fl_Menu_Item mc_PlotDrop = {"Drop Plot",0,(Fl_Callback*)cb_Nothing};
Fl_Menu_Item mc_PlotVelocity = {"Velocity Plot",0,(Fl_Callback*)cb_Nothing};
Fl_Menu_Item mc_PlotEnergy = {"Energy Plot",0,(Fl_Callback*)cb_Nothing};
Fl_Menu_Item mc_PlotWind = {"Wind drift Plot",0,(Fl_Callback*)cb_Nothing};
// Set initial condition for menu items.
m_Analyze.deactivate();
m_Aids.deactivate();
// These are planned features, but haven't been done yet.
mc_Open.deactivate(); // The open and save will be done together.
mc_Save.deactivate();
mc_Export.deactivate(); // Lower priority, but needs to be done.
////// TODO //////
mc_Advanced.deactivate(); // Maybe no need?
mc_Copy.deactivate(); // Can't figure out how to make this work. User can use Ctrl-c until I get some help.
mc_Options.deactivate(); // Eventually add support for metric
mc_Compare.deactivate();
mc_Plot.deactivate();
mc_RangeCard.deactivate();
mc_ClickChart.deactivate();
mc_RangeTable.deactivate();
mc_Table.deactivate();
mc_CalcBC.deactivate();
mc_OptimizePBR.deactivate();
mc_Store1.deactivate();
mc_Store2.deactivate();
mc_Store3.deactivate();
mc_Store4.deactivate();
mc_Store5.deactivate();
mc_CompareTable.deactivate();
mc_ComparePlot.deactivate();
Fl_Menu_Item menuitems[] = {
m_File, //1
mc_New,
mc_Open,
mc_Save,
mc_Export,
mc_Quit,
{0},//7
m_Edit,
mc_Copy,
mc_Paste,
mc_Options,
{0},
m_Solution, //12
mc_Solve,
mc_Table,
mc_Plot,
mc_Compare,
mc_RangeCard,
mc_ClickChart,
mc_RangeTable,
{0}, // 21
m_Tools,
mc_OptimizePBR,
mc_CalcBC,
{0},
m_Compare,
mc_Store1,
mc_Store2,
mc_Store3,
mc_Store4,
mc_Store5,
mc_CompareTable,
mc_CompareDrop,
mc_CompareVelocity,
mc_CompareEnergy,
mc_CompareWind,
{0},
mc_ComparePlot,
mc_PlotDrop,
mc_PlotVelocity,
mc_PlotEnergy,
mc_PlotWind,
{0},
{0},
m_Help, //26
mc_Help,
mc_License,
mc_About,
mc_Bug,
{0}, //31
{0}
};
menu->copy(menuitems);
end();
//resizable(this);
show();
}
InputWindow::~InputWindow(){
if (Solution!=NULL) {
free(Solution);
Solution=NULL;
}
}
void InputWindow::cb_ckWeather(Fl_Widget* o, void* v){
InputWindow* T=(InputWindow*)v;
if (T->ckWeather->value()==1){
T->inTemp->activate();
T->inPressure->activate();
T->inAltitude->activate();
T->inHumidity->activate();
}
else if (T->ckWeather->value()==0){
T->inTemp->deactivate();
T->inPressure->deactivate();
T->inAltitude->deactivate();
T->inHumidity->deactivate();
}
}
void InputWindow::cb_Solve(Fl_Widget* o, void* vd) {
DisableMenu(vd);
InputWindow* T = (InputWindow*)vd;
if (T->Solution != NULL) {
free(T->Solution);
T->Solution=NULL;
}
double bc=-1; // The ballistic coefficient for the projectile.
double v=-1; // Intial velocity, in ft/s
double sh=-1; // The Sight height over bore, in inches.
double angle=-1; // The shooting angle (uphill / downhill), in degrees.
double zero=-1; // The zero range of the rifle, in yards.
double windspeed=-1; // The wind speed in miles per hour.
double windangle=-1; // The wind angle (0=headwind, 90=right to left, 180=tailwind, 270/-90=left to right)
int df=0;
int numRows=0;
char txt1[1024];
double zeroangle=-1; // The bore / sight angle.
bc = atof(T->inBC->value());
v = atof(T->inMV->value());
sh = atof(T->inSH->value());
angle=atof(T->inAngle->value());
zero=atof(T->inZero->value());
windspeed=atof(T->inVwind->value());
windangle=atof(T->inAwind->value());
if (T->inG1->value()==1) df=G1;
else if (T->inG2->value()==1) df=G2;
else if (T->inG5->value()==1) df=G5;
else if (T->inG6->value()==1) df=G6;
else if (T->inG7->value()==1) df=G7;
else if (T->inG8->value()==1) df=G8;
if (T->ckWeather->value()==1){
double Altitude = atof(T->inAltitude->value());
double Barometer = atof(T->inPressure->value());
double Temperature = atof(T->inTemp->value());
double RH = atof(T->inHumidity->value())/100;
bc = AtmCorrect(bc, Altitude,Barometer,Temperature,RH);
}
zeroangle=ZeroAngle(df,bc,v,1.6,zero,0);
numRows = SolveAll(df,bc,v,sh,angle,zeroangle,windspeed,windangle,&(T->Solution));
if (numRows>0 && T->Solution!=NULL){ // Solution is valid with no errors.
// Store some general data about the load and weather conditions in the 2048 extra bytes.
T->gsln = new GBCSolution(
T->Solution,
T->inName->value(),
atof(T->inBC->value()),
atof(T->inSH->value()),
atoi(T->inWeight->value()),
atoi(T->inMV->value()),
atoi(T->inAngle->value()),
atoi(T->inZero->value()),
atoi(T->inVwind->value()),
atoi(T->inAwind->value()),
atoi(T->inTemp->value()),
atoi(T->inHumidity->value()),
atof(T->inPressure->value()),
atoi(T->inAltitude->value()),
(int)T->Solution[10*__BCOMP_MAXRANGE__+1]
);
// Inform the user of our success.
sprintf(txt1,"GNU Ballistics Computer: Solution Valid.\nSolution's maximum valid range is %d yards\nUse the options in the 'Solution' menu to view results.",numRows-2);
// SEGMENTATION FAULT IS CAUSED BY THIS LINE ???
T->oStatus->value(txt1);
EnableMenu((InputWindow*) vd);
}
return;
}
void InputWindow::EnableMenu(void* v){
InputWindow* T = (InputWindow*)v;
// Enable the Analyze and Shooting Aids menu items.
Fl_Menu_Item* mp;
mp=(Fl_Menu_Item*)&(T->menu->menu()[14]);
mp->activate();
// mp=(Fl_Menu_Item*)&(T->menu->menu()[17]);
// mp->activate();
T->redraw();
}
void InputWindow::DisableMenu(void* v){
InputWindow* T = (InputWindow*)v;
// Enable the Analyze and Shooting Aids menu items.
Fl_Menu_Item* mp;
mp=(Fl_Menu_Item*)&(T->menu->menu()[14]);
mp->deactivate();
// mp=(Fl_Menu_Item*)&(T->menu->menu()[17]);
// mp->deactivate();
T->redraw();
}
void InputWindow::cb_copy_i() {
// out->value(inp->value());
}
void InputWindow::cb_File(Fl_Widget*, void* v) {
// out->value(inp->value());
}
void InputWindow::cb_Nothing(Fl_Widget*, void* v) {
// out->value(inp->value());
}
void InputWindow::cb_Quit(Fl_Widget*, void* v) {
exit(0);
}
void InputWindow::cb_Clear(Fl_Widget* o, void* v) {
DisableMenu(v);
InputWindow* T=(InputWindow*)v;
T->inBC->value("0.465");
T->inMV->value("2650");
T->inZero->value("200");
T->inAngle->value("0");
T->inSH->value("1.6");
T->inVwind->value("0");
T->inAwind->value("0");
T->inTemp->value("59");
T->inWeight->value("168");
T->inAltitude->value("0");
T->inPressure->value("29.53");
T->inHumidity->value("78");
T->ckWeather->clear();
T->cb_ckWeather(o,v);
T->oStatus->value("GNU Ballistic Computer: Solution Reset");
if (T->Solution != NULL) {
free(T->Solution);
T->Solution=NULL;
}
}
void InputWindow::cb_mNew(Fl_Widget* o, void* v){
DisableMenu(v);
InputWindow* T=(InputWindow*)v;
T->cb_Clear(o,v);
T->oStatus->value("GNU Ballistic Computer: Solution cleared. \nNow begin new Solution");
}
void InputWindow::cb_quit(Fl_Widget* o, void* v) {
( (InputWindow*)v )->cb_quit_i();
}
void InputWindow::cb_quit_i() {
hide();
}
void InputWindow::cb_mOpen(Fl_Widget* o, void* v) {
DisableMenu(v);
InputWindow* T = (InputWindow*)v;
T->oStatus->value("Select file to load...");
}
void InputWindow::cb_RangeTable(Fl_Widget*, void* v){
InputWindow* T = (InputWindow*)v;
char str[100];
strcpy(str,"Range Table: ");
RangeWindow* Rw = new RangeWindow(600,400,T->gsln);
}
void InputWindow::cb_Paste(Fl_Widget* r, void* v){
InputWindow* T = (InputWindow*)v;
T->Paste();
}
void InputWindow::cb_Copy(Fl_Widget* r, void* v){
InputWindow* T = (InputWindow*)v;
T->Copy();
}
void InputWindow::Paste(){
Fl::paste(*this,1);
}
void InputWindow::Copy(){
//int len = Fl::event_length();
//Fl::copy(Fl::event_text(),len,1);
//printf("\nLENGTH: %d Text: %s",len,Fl::event_text());
// 2nd try?
// this->handle(FL_CTRL + 'c');
// Can't figure out how to do this?? very strange...
}

110
InputWindow.h

@ -0,0 +1,110 @@ @@ -0,0 +1,110 @@
#ifndef __INPUTWINDOW
#define __INPUTWINDOW
#include <FL/Fl_BMP_Image.H>
class InputWindow : public Fl_Window{
public:
InputWindow(int w, int h, const char* title );
~InputWindow();
Fl_Button* btSolve;
Fl_Button* btReset;
Fl_Button* btStdAtmosphere;
Fl_Button* btShowChart;
Fl_Button* btPlot;
Fl_Button* btCompare;
Fl_Button* btSaveSolution;
Fl_Button* btLoadSolution;
double* Solution;
GBCSolution* gsln;
// Drag function selection pointers.
Fl_Round_Button* inG1;
Fl_Round_Button* inG2;
Fl_Round_Button* inG5;
Fl_Round_Button* inG6;
Fl_Round_Button* inG7;
Fl_Round_Button* inG8;
Fl_Check_Button* ckWeather;
Fl_Input* inName;
Fl_Int_Input* inWeight;
Fl_Float_Input* inBC;
Fl_Float_Input* inSH;
Fl_Int_Input* inMV;
Fl_Int_Input* inAngle;
Fl_Int_Input* inZero;
Fl_Int_Input* inVwind;
Fl_Int_Input* inAwind;
Fl_Int_Input* inTemp;
Fl_Float_Input* inPressure;
Fl_Int_Input* inHumidity;
Fl_Int_Input* inAltitude;
//Fl_Input* inStepSize;
Fl_Menu_Bar *menu;
Fl_Menu_Item *pmenuitems;
// Menu Item Declarations.
Fl_Menu_Item m_File;
Fl_Menu_Item mc_New;
Fl_Menu_Item mc_Open;
Fl_Menu_Item mc_Save;
Fl_Menu_Item mc_Export;
Fl_Menu_Item mc_Quit;
Fl_Menu_Item m_Edit;
Fl_Menu_Item mc_Copy;
Fl_Menu_Item mc_Paste;
Fl_Menu_Item mc_Options;
Fl_Menu_Item m_Analyze;
Fl_Menu_Item mc_Table;
Fl_Menu_Item mc_Plot;
Fl_Menu_Item mc_Compare;
Fl_Menu_Item m_Aids;
Fl_Menu_Item mc_RangeCard;
Fl_Menu_Item mc_ClickChart;
Fl_Menu_Item mc_RangeTable;
Fl_Menu_Item m_Solution;
Fl_Menu_Item mc_Solve;
Fl_Menu_Item mc_Data;
Fl_Menu_Item mc_Advanced;
Fl_Menu_Item m_Help;
Fl_Menu_Item mc_Help;
Fl_Menu_Item mc_License;
Fl_Menu_Item mc_About;
Fl_Menu_Item mc_Bug;
Fl_Multiline_Output* oStatus;
// FL Outputs
Fl_Output* out;
private:
static void cb_Solve(Fl_Widget*, void*);
inline void cb_copy_i();
static void cb_quit(Fl_Widget*, void*);
inline void cb_quit_i();
static void cb_File(Fl_Widget*, void*);
static void cb_Quit(Fl_Widget*, void*);
static void cb_Nothing(Fl_Widget*, void*);
static void cb_ckWeather(Fl_Widget*, void*);
static void cb_Clear(Fl_Widget*, void*);
static void cb_mNew(Fl_Widget*, void*);
static void cb_mOpen(Fl_Widget* , void* );
static void EnableMenu(void*);
static void DisableMenu(void*);
static void cb_RangeTable(Fl_Widget*, void* );
static void cb_Paste(Fl_Widget*, void* v);
static void cb_Copy(Fl_Widget*, void* v);
void Paste(void);
void Copy(void);
};
#endif

4
Makefile

@ -0,0 +1,4 @@ @@ -0,0 +1,4 @@
All:
fltk-config --use-images --compile GNU_Ballistics.cpp

662
RangeWindow.cpp

@ -0,0 +1,662 @@ @@ -0,0 +1,662 @@
RangeWindow::RangeWindow(int w, int h, GBCSolution* inSLN):Fl_Window(w,h,inSLN->Name()){
begin();
menu = new Fl_Menu_Bar(0,0,w,30,"MENU");
Sln=inSLN;
Fl_Menu_Item items[]= {
{"&File",0,0,0,FL_SUBMENU},
{"Export Data",0,0,0,FL_SUBMENU},
{"Comma delimited (.csv)",0,(Fl_Callback*)cb_ExportCSV,this,0},
{"Excel Spreadsheet (.xls)",0,(Fl_Callback*)cb_ExportExcel,this,0},
{"OpenOffice Spreadsheet (.ods)",0,(Fl_Callback*)cb_ExportOO,this,0},
{"HTML Table (.html)",0,(Fl_Callback*)cb_ExportHTML,this,0},
{"SQL Insert Statement (.sql)",0,(Fl_Callback*)cb_ExportSQL,this,0},
{"XML File (.xml)",0,(Fl_Callback*)cb_ExportXML,this,0},
{0},
{"&Close",0,(Fl_Callback*)cb_Close,this,0},
{0},
{"&Minimum Range",0,0,0,FL_SUBMENU},
{"0",0,(Fl_Callback*)cb_Min0,this,FL_MENU_RADIO|FL_MENU_VALUE},
{"50",0,(Fl_Callback*)cb_Min50,this,FL_MENU_RADIO},
{"100",0,(Fl_Callback*)cb_Min100,this,FL_MENU_RADIO},
{"250",0,(Fl_Callback*)cb_Min250,this,FL_MENU_RADIO},
{"500",0,(Fl_Callback*)cb_Min500,this,FL_MENU_RADIO},
{"750",0,(Fl_Callback*)cb_Min750,this,FL_MENU_RADIO},
{"1000",0,(Fl_Callback*)cb_Min1000,this,FL_MENU_RADIO},
{"2000",0,(Fl_Callback*)cb_Min2000,this,FL_MENU_RADIO},
{0},
{"&Maximum Range",0,0,0,FL_SUBMENU},
{"100",0,(Fl_Callback*)cb_Max100,this,FL_MENU_RADIO},
{"250",0,(Fl_Callback*)cb_Max250,this,FL_MENU_RADIO},
{"500",0,(Fl_Callback*)cb_Max500,this,FL_MENU_RADIO},
{"750",0,(Fl_Callback*)cb_Max750,this,FL_MENU_RADIO},
{"1000",0,(Fl_Callback*)cb_Max1000,this,FL_MENU_RADIO|FL_MENU_VALUE},
{"1760",0,(Fl_Callback*)cb_Max1760,this,FL_MENU_RADIO},
{"2000",0,(Fl_Callback*)cb_Max2000,this,FL_MENU_RADIO},
{"MAX",0,(Fl_Callback*)cb_MaxMax,this,FL_MENU_RADIO},
{0},
{"&Step Size",0,0,0,FL_SUBMENU},
{"1",0,(Fl_Callback*)cb_Step1,this,FL_MENU_RADIO},
{"5",0,(Fl_Callback*)cb_Step5,this,FL_MENU_RADIO},
{"10",0,(Fl_Callback*)cb_Step10,this,FL_MENU_RADIO|FL_MENU_VALUE},
{"25",0,(Fl_Callback*)cb_Step25,this,FL_MENU_RADIO},
{"50",0,(Fl_Callback*)cb_Step50,this,FL_MENU_RADIO},
{"100",0,(Fl_Callback*)cb_Step100,this,FL_MENU_RADIO},
{"250",0,(Fl_Callback*)cb_Step250,this,FL_MENU_RADIO},
{0},
{0}
};
menu->copy(items);
tbl = new Fl_Browser(5,35,w-10,h-40,"Hello");
colwidths = (int*)malloc(10*sizeof(int));
colwidths[0]=70; // Range (yds)
colwidths[1]=70; // Drop (in)
colwidths[2]=70; // Drop (MOA)
colwidths[3]=70; // Vel (ft/s)
colwidths[4]=70; // Energy (ft-lb)
colwidths[5]=70; // Winddrift (in)
colwidths[6]=70; // Windage (ft)
colwidths[7]=70; // Time (s)
colwidths[8]=0;
tbl->column_widths(colwidths);
tbl->column_char('\t');
min=0;
max=1000;
step=10;
GenTable();
end();
show();
}
void RangeWindow::GenTable(){
double r,p,m,v,e,wi,wm,t;
tbl->clear();
int MIN=this->min;
int MAX=this->max;
int STEP=this->step;
int num=Sln->MaxRows();
// printf("NUM: %d",num);
if (MAX>num) MAX=num;
if (MIN>MAX) MIN=MAX;
char* str = (char*)malloc(1024*sizeof(char));
// Print some general information about the load.
sprintf(str,"@b%s",Sln->Name()); tbl->add(str);
sprintf(str,"Drag Coefficient: %.3f Projectile Weight: %d grains",Sln->BC(), Sln->Weight()); tbl->add(str);
sprintf(str,"Initial Velocity: %d (ft/s) Zero Range: %d yards Shooting Angle: %d degrees",Sln->MuzzleVelocity(), Sln->ZeroRange(), Sln->ShootingAngle()); tbl->add(str);
sprintf(str,"Wind Velocity: %d mph Wind Direction: %d degrees",Sln->WindSpeed(), Sln->WindAngle()); tbl->add(str);
sprintf(str,"Altitude: %d feet Barometer: %.2f in-Hg Temperature: %d F Relative Humidity: %d%%",Sln->Altitude(), Sln->Pressure(), Sln->Temp(), Sln->Humidity()); tbl->add(str);
tbl->add("");
tbl->add("@b@cRange\t@b@cDrop\t@b@cDrop\t@b@cVelocity\t@b@cEnergy\t@b@cWind Drift\t@b@cWindage\t@b@cTime",0);
tbl->add("@c(yards)\t@c(inches)\t@c(MOA)\t@c(ft/s)\t@c(ft-lb)\t@c(inches)\t@c(MOA)\t@c(s)",0);
for (int n=MIN;n<=MAX;n=n+STEP){
r=Sln->GetRange(n);
p=Sln->GetPath(n);
m=Sln->GetMOA(n);
v=Sln->GetVelocity(n);
wi=Sln->GetWindage(n);
wm=Sln->GetWindageMOA(n);
t=Sln->GetTime(n);
e=Sln->Weight()*v*v/450436;
sprintf(str,"@c%.0f\t@c%.2f\t@c%.2f\t@c%.0f\t@c%.0f\t@c%.2f\t@c%.2f\t@c%.2f",r,p,m,v,e,wi,wm,t);
tbl->add(str,0);
}
}
RangeWindow::~RangeWindow(){
}
void RangeWindow::cb_Nothing(Fl_Widget* t, void* v){
//exit(0);
}
void RangeWindow::cb_Min0(Fl_Widget* t, void* v){
RangeWindow* T=(RangeWindow*)v;
T->min=0;
T->GenTable();
}
void RangeWindow::cb_Min50(Fl_Widget* t, void* v){
RangeWindow* T=(RangeWindow*)v;
T->min=50;
T->GenTable();
}
void RangeWindow::cb_Min100(Fl_Widget* t, void* v){
RangeWindow* T=(RangeWindow*)v;
T->min=100;
T->GenTable();
}
void RangeWindow::cb_Min250(Fl_Widget* t, void* v){
RangeWindow* T=(RangeWindow*)v;
T->min=250;
T->GenTable();
}
void RangeWindow::cb_Min500(Fl_Widget* t, void* v){
RangeWindow* T=(RangeWindow*)v;
T->min=500;
T->GenTable();
}
void RangeWindow::cb_Min750(Fl_Widget* t, void* v){
RangeWindow* T=(RangeWindow*)v;
T->min=750;
T->GenTable();
}
void RangeWindow::cb_Min1000(Fl_Widget* t, void* v){
RangeWindow* T=(RangeWindow*)v;
T->min=1000;
T->GenTable();
}
void RangeWindow::cb_Min2000(Fl_Widget* t, void* v){
RangeWindow* T=(RangeWindow*)v;
T->min=2000;
T->GenTable();
}
void RangeWindow::cb_Max100(Fl_Widget* t, void* v){
RangeWindow* T=(RangeWindow*)v;
T->max=100;
T->GenTable();
}
void RangeWindow::cb_Max250(Fl_Widget* t, void* v){
RangeWindow* T=(RangeWindow*)v;
T->max=250;
T->GenTable();
}
void RangeWindow::cb_Max500(Fl_Widget* t, void* v){
RangeWindow* T=(RangeWindow*)v;
T->max=500;
T->GenTable();
}
void RangeWindow::cb_Max750(Fl_Widget* t, void* v){
RangeWindow* T=(RangeWindow*)v;
T->max=750;
T->GenTable();
}
void RangeWindow::cb_Max1000(Fl_Widget* t, void* v){
RangeWindow* T=(RangeWindow*)v;
T->max=1000;
T->GenTable();
}
void RangeWindow::cb_Max1760(Fl_Widget* t, void* v){
RangeWindow* T=(RangeWindow*)v;
T->max=1760;
T->GenTable();
}
void RangeWindow::cb_Max2000(Fl_Widget* t, void* v){
RangeWindow* T=(RangeWindow*)v;
T->max=2000;
T->GenTable();
}
void RangeWindow::cb_MaxMax(Fl_Widget* t, void* v){
RangeWindow* T=(RangeWindow*)v;
T->max=__BCOMP_MAXRANGE__;
T->GenTable();
}
void RangeWindow::cb_Step1(Fl_Widget* t, void* v){
RangeWindow* T=(RangeWindow*)v;
T->step=1;
T->GenTable();
}
void RangeWindow::cb_Step5(Fl_Widget* t, void* v){
RangeWindow* T=(RangeWindow*)v;
T->step=5;
T->GenTable();
}
void RangeWindow::cb_Step10(Fl_Widget* t, void* v){
RangeWindow* T=(RangeWindow*)v;
T->step=10;
T->GenTable();
}
void RangeWindow::cb_Step25(Fl_Widget* t, void* v){
RangeWindow* T=(RangeWindow*)v;
T->step=25;
T->GenTable();
}
void RangeWindow::cb_Step50(Fl_Widget* t, void* v){
RangeWindow* T=(RangeWindow*)v;
T->step=50;
T->GenTable();
}
void RangeWindow::cb_Step100(Fl_Widget* t, void* v){
RangeWindow* T=(RangeWindow*)v;
T->step=100;
T->GenTable();
}
void RangeWindow::cb_Step250(Fl_Widget* t, void* v){
RangeWindow* T=(RangeWindow*)v;
T->step=250;
T->GenTable();
}
void RangeWindow::cb_ExportCSV(Fl_Widget* f, void* vtt){
RangeWindow* T = (RangeWindow*)vtt;
char* fname=NULL;
fname = fl_file_chooser("Please select a location and filename to export the CSV data.","*.csv","OutputData.csv",0);
if (fname==NULL) return;
FILE* ofile = fopen(fname,"w");
// Print the output to a file.
double r,p,m,v,e,wi,wm,t;
int MIN=T->min;
int MAX=T->max;
int STEP=T->step;
fprintf(ofile, "Range,Drop,Drop,Velocity,Energy,Wind Drift,Windage,Time",0);
fprintf(ofile, "\n(yards),(inches),(MOA),(ft/s),(ft-lb),(inches),(MOA),(s)",0);
int num=T->Sln->MaxRows();
if (MAX>num) MAX=num;
if (MIN>MAX) MIN=MAX;
char* str = (char*)malloc(1024*sizeof(char));
for (int n=MIN;n<=MAX;n=n+STEP){
r=T->Sln->GetRange(n);
p=T->Sln->GetPath(n);
m=T->Sln->GetMOA(n);
v=T->Sln->GetVelocity(n);
e=0;
wi=T->Sln->GetWindage(n);
wm=T->Sln->GetWindageMOA(n);
t=T->Sln->GetTime(n);
e=T->Sln->Weight()*v*v/450436;
fprintf(ofile,"\n%.0f,%.2f,%.2f,%.0f,%.2f,%.2f,%.2f,%.2f",r,p,m,v,e,wi,wm,t);
}
fclose(ofile);
}
void RangeWindow::cb_ExportExcel(Fl_Widget* f, void* vtt){
RangeWindow* T = (RangeWindow*)vtt;
char* fname=NULL;
fname = fl_file_chooser("Please select a location and filename to export the Excel data.","*.xls","OutputData.xls",0);
if (fname==NULL) return;
FILE* ofile = fopen(fname,"w");
// Print the output to a file.
double r,p,m,v,e,wi,wm,t;
int MIN=T->min;
int MAX=T->max;
int STEP=T->step;
fprintf(ofile, "\n<html><head><title>$s</title></head>",0);
fprintf(ofile, "\n\n<table><tr>");
fprintf(ofile, "<td>Range</td>\
<td>Drop</td>\
<td>Drop</td>\
<td>Velocity</td>\
<td>Energy</td>\
<td>Winddrift</td>\
<td>Windage</td>\
<td>Time</td></tr>"
);
fprintf(ofile,"\n<tr>");
fprintf(ofile, "<td>(yards)</td>\
<td>(inches)</td>\
<td>(MOA)</td>\
<td>(ft/s)</td>\
<td>(ft-lb/grn)</td>\
<td>(inches)</td>\
<td>(MOA)</td>\
<td>(s)</td>"
);
int num=T->Sln->MaxRows();
if (MAX>num) MAX=num;
if (MIN>MAX) MIN=MAX;
char* str = (char*)malloc(1024*sizeof(char));
for (int n=MIN;n<=MAX;n=n+STEP){
r=T->Sln->GetRange(n);
p=T->Sln->GetPath(n);
m=T->Sln->GetMOA(n);
v=T->Sln->GetVelocity(n);
e=0;
wi=T->Sln->GetWindage(n);
wm=T->Sln->GetWindageMOA(n);
t=T->Sln->GetTime(n);
e=T->Sln->Weight()*v*v/450436;
fprintf(ofile,"\n<tr>\
<td>%.0f</td>\
<td>%.2f</td>\
<td>%.2f</td>\
<td>%.0f</td>\
<td>%.2f</td>\
<td>%.2f</td>\
<td>%.2f</td>\
<td>%.2f</td></tr>",
r,p,m,v,e,wi,wm,t);
}
fprintf(ofile,"\n</table></html>");
fclose(ofile);
}
void RangeWindow::cb_ExportOO(Fl_Widget* f, void* vtt){
RangeWindow* T = (RangeWindow*)vtt;
char* fname=NULL;
fname = fl_file_chooser("Please select a location and filename to export the OpenOffice spreadsheet.","*.ods","OutputData.ods",0);
if (fname==NULL) return;
FILE* ofile = fopen(fname,"w");
// Print the output to a file.
double r,p,m,v,e,wi,wm,t;
int MIN=T->min;
int MAX=T->max;
int STEP=T->step;
fprintf(ofile, "\n<html><head><title>%s</title></head>",0);
fprintf(ofile, "\n\n<table><tr>");
fprintf(ofile, "\n<td>Range</td>\
\n<td>Drop</td>\
\n<td>Drop</td>\
\n<td>Velocity</td>\
\n<td>Energy</td>\
\n<td>Winddrift</td>\
\n<td>Windage</td>\
\n<td>Time</td></tr>"
);
fprintf(ofile,"\n\n<tr>");
fprintf(ofile, "\n<td>(yards)</td>\
\n<td>(inches)</td>\
\n<td>(MOA)</td>\
\n<td>(ft/s)</td>\
\n<td>(ft-lb/grn)</td>\
\n<td>(inches)</td>\
\n<td>(MOA)</td>\
\n<td>(s)</td>"
);
int num=T->Sln->MaxRows();
if (MAX>num) MAX=num;
if (MIN>MAX) MIN=MAX;
char* str = (char*)malloc(1024*sizeof(char));
for (int n=MIN;n<=MAX;n=n+STEP){
r=T->Sln->GetRange(n);
p=T->Sln->GetPath(n);
m=T->Sln->GetMOA(n);
v=T->Sln->GetVelocity(n);
e=0;
wi=T->Sln->GetWindage(n);
wm=T->Sln->GetWindageMOA(n);
t=T->Sln->GetTime(n);
e=T->Sln->Weight()*v*v/450436;
fprintf(ofile,"\n<tr>\
\n<td>%.0f</td>\
\n<td>%.2f</td>\
\n<td>%.2f</td>\
\n<td>%.0f</td>\
\n<td>%.2f</td>\
\n<td>%.2f</td>\
\n<td>%.2f</td>\
\n<td>%.2f</td></tr>",
r,p,m,v,e,wi,wm,t);