Add a simple license key: I take the CRC of the license info, plus
some magic numbers. This would be trivial to break, but still more difficult than patching the binary to skip the check... [git-p4: depot-paths = "//depot/solvespace/": change = 1853]solver
parent
5a2803617b
commit
0c10efdab6
2
Makefile
2
Makefile
|
@ -39,7 +39,7 @@ SSOBJS = $(OBJDIR)\solvespace.obj \
|
||||||
RES = $(OBJDIR)\resource.res
|
RES = $(OBJDIR)\resource.res
|
||||||
|
|
||||||
|
|
||||||
LIBS = user32.lib gdi32.lib comctl32.lib advapi32.lib opengl32.lib glu32.lib \
|
LIBS = user32.lib gdi32.lib comctl32.lib advapi32.lib shell32.lib opengl32.lib glu32.lib \
|
||||||
extlib\libpng.lib extlib\zlib.lib
|
extlib\libpng.lib extlib\zlib.lib
|
||||||
|
|
||||||
all: $(OBJDIR)/solvespace.exe
|
all: $(OBJDIR)/solvespace.exe
|
||||||
|
|
|
@ -1304,7 +1304,7 @@ for new users; to learn about this program, see the video tutorials.
|
||||||
<h2>Licensing</h2>
|
<h2>Licensing</h2>
|
||||||
|
|
||||||
As downloaded, MechSketch does not include a license key. This means
|
As downloaded, MechSketch does not include a license key. This means
|
||||||
that it cannot create files with more than seven groups. Larger files
|
that it cannot create files with more than six groups. Larger files
|
||||||
may be opened, but not modified. This light version of MechSketch
|
may be opened, but not modified. This light version of MechSketch
|
||||||
is intended for evaluation, but non-commercial / personal use is
|
is intended for evaluation, but non-commercial / personal use is
|
||||||
also permitted.
|
also permitted.
|
||||||
|
|
112
export.cpp
112
export.cpp
|
@ -117,46 +117,46 @@ havepoly:
|
||||||
|
|
||||||
// Some software, like Adobe Illustrator, insists on a header.
|
// Some software, like Adobe Illustrator, insists on a header.
|
||||||
fprintf(f,
|
fprintf(f,
|
||||||
" 999\n"
|
" 999\r\n"
|
||||||
"file created by SolveSpace\n"
|
"file created by SolveSpace\r\n"
|
||||||
" 0\n"
|
" 0\r\n"
|
||||||
"SECTION\n"
|
"SECTION\r\n"
|
||||||
" 2\n"
|
" 2\r\n"
|
||||||
"HEADER\n"
|
"HEADER\r\n"
|
||||||
" 9\n"
|
" 9\r\n"
|
||||||
"$ACADVER\n"
|
"$ACADVER\r\n"
|
||||||
" 1\n"
|
" 1\r\n"
|
||||||
"AC1006\n"
|
"AC1006\r\n"
|
||||||
" 9\n"
|
" 9\r\n"
|
||||||
"$INSBASE\n"
|
"$INSBASE\r\n"
|
||||||
" 10\n"
|
" 10\r\n"
|
||||||
"0.0\n"
|
"0.0\r\n"
|
||||||
" 20\n"
|
" 20\r\n"
|
||||||
"0.0\n"
|
"0.0\r\n"
|
||||||
" 30\n"
|
" 30\r\n"
|
||||||
"0.0\n"
|
"0.0\r\n"
|
||||||
" 9\n"
|
" 9\r\n"
|
||||||
"$EXTMIN\n"
|
"$EXTMIN\r\n"
|
||||||
" 10\n"
|
" 10\r\n"
|
||||||
"0.0\n"
|
"0.0\r\n"
|
||||||
" 20\n"
|
" 20\r\n"
|
||||||
"0.0\n"
|
"0.0\r\n"
|
||||||
" 9\n"
|
" 9\r\n"
|
||||||
"$EXTMAX\n"
|
"$EXTMAX\r\n"
|
||||||
" 10\n"
|
" 10\r\n"
|
||||||
"10000.0\n"
|
"10000.0\r\n"
|
||||||
" 20\n"
|
" 20\r\n"
|
||||||
"10000.0\n"
|
"10000.0\r\n"
|
||||||
" 0\n"
|
" 0\r\n"
|
||||||
"ENDSEC\n");
|
"ENDSEC\r\n");
|
||||||
|
|
||||||
// Now begin the entities, which are just line segments reproduced from
|
// Now begin the entities, which are just line segments reproduced from
|
||||||
// our piecewise linear curves.
|
// our piecewise linear curves.
|
||||||
fprintf(f,
|
fprintf(f,
|
||||||
" 0\n"
|
" 0\r\n"
|
||||||
"SECTION\n"
|
"SECTION\r\n"
|
||||||
" 2\n"
|
" 2\r\n"
|
||||||
"ENTITIES\n");
|
"ENTITIES\r\n");
|
||||||
|
|
||||||
int i, j;
|
int i, j;
|
||||||
for(i = 0; i < sp->l.n; i++) {
|
for(i = 0; i < sp->l.n; i++) {
|
||||||
|
@ -172,22 +172,22 @@ havepoly:
|
||||||
double s = SS.exportScale;
|
double s = SS.exportScale;
|
||||||
|
|
||||||
fprintf(f,
|
fprintf(f,
|
||||||
" 0\n"
|
" 0\r\n"
|
||||||
"LINE\n"
|
"LINE\r\n"
|
||||||
" 8\n" // Layer code
|
" 8\r\n" // Layer code
|
||||||
"%d\n"
|
"%d\r\n"
|
||||||
" 10\n" // xA
|
" 10\r\n" // xA
|
||||||
"%.6f\n"
|
"%.6f\r\n"
|
||||||
" 20\n" // yA
|
" 20\r\n" // yA
|
||||||
"%.6f\n"
|
"%.6f\r\n"
|
||||||
" 30\n" // zA
|
" 30\r\n" // zA
|
||||||
"%.6f\n"
|
"%.6f\r\n"
|
||||||
" 11\n" // xB
|
" 11\r\n" // xB
|
||||||
"%.6f\n"
|
"%.6f\r\n"
|
||||||
" 21\n" // yB
|
" 21\r\n" // yB
|
||||||
"%.6f\n"
|
"%.6f\r\n"
|
||||||
" 31\n" // zB
|
" 31\r\n" // zB
|
||||||
"%.6f\n",
|
"%.6f\r\n",
|
||||||
0,
|
0,
|
||||||
e0.x/s, e0.y/s, 0.0,
|
e0.x/s, e0.y/s, 0.0,
|
||||||
e1.x/s, e1.y/s, 0.0);
|
e1.x/s, e1.y/s, 0.0);
|
||||||
|
@ -195,10 +195,10 @@ havepoly:
|
||||||
}
|
}
|
||||||
|
|
||||||
fprintf(f,
|
fprintf(f,
|
||||||
" 0\n"
|
" 0\r\n"
|
||||||
"ENDSEC\n"
|
"ENDSEC\r\n"
|
||||||
" 0\n"
|
" 0\r\n"
|
||||||
"EOF\n" );
|
"EOF\r\n" );
|
||||||
|
|
||||||
spa.Clear();
|
spa.Clear();
|
||||||
fclose(f);
|
fclose(f);
|
||||||
|
|
|
@ -7,6 +7,7 @@
|
||||||
#define mFile (&SolveSpace::MenuFile)
|
#define mFile (&SolveSpace::MenuFile)
|
||||||
#define mGrp (&Group::MenuGroup)
|
#define mGrp (&Group::MenuGroup)
|
||||||
#define mAna (&SolveSpace::MenuAnalyze)
|
#define mAna (&SolveSpace::MenuAnalyze)
|
||||||
|
#define mHelp (&SolveSpace::MenuHelp)
|
||||||
#define S 0x100
|
#define S 0x100
|
||||||
#define C 0x200
|
#define C 0x200
|
||||||
const GraphicsWindow::MenuEntry GraphicsWindow::menu[] = {
|
const GraphicsWindow::MenuEntry GraphicsWindow::menu[] = {
|
||||||
|
@ -101,11 +102,11 @@ const GraphicsWindow::MenuEntry GraphicsWindow::menu[] = {
|
||||||
{ 1, "&Stop Tracing...\tCtrl+Shift+S", MNU_STOP_TRACING, 'S'|S|C,mAna },
|
{ 1, "&Stop Tracing...\tCtrl+Shift+S", MNU_STOP_TRACING, 'S'|S|C,mAna },
|
||||||
{ 1, "Step &Dimension...\tCtrl+Shift+D", MNU_STEP_DIM, 'D'|S|C,mAna },
|
{ 1, "Step &Dimension...\tCtrl+Shift+D", MNU_STEP_DIM, 'D'|S|C,mAna },
|
||||||
|
|
||||||
{ 0, "&Help", 0, NULL },
|
{ 0, "&Help", 0, 0, NULL },
|
||||||
{ 1, "&Load License...", 0, NULL },
|
{ 1, "&Load License...", MNU_LICENSE, 0, mHelp },
|
||||||
{ 1, NULL, 0, NULL },
|
{ 1, NULL, 0, 0, NULL },
|
||||||
{ 1, "&Website / Manual", 0, NULL },
|
{ 1, "&Website / Manual", MNU_WEBSITE, 0, mHelp },
|
||||||
{ 1, "&About", 0, NULL },
|
{ 1, "&About", MNU_ABOUT, 0, mHelp },
|
||||||
{ -1 },
|
{ -1 },
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -17,6 +17,14 @@ void Group::AddParam(IdList<Param,hParam> *param, hParam hp, double v) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void Group::MenuGroup(int id) {
|
void Group::MenuGroup(int id) {
|
||||||
|
if(!SS.license.licensed && SS.group.n >= 7) {
|
||||||
|
Error("The free version of this software does not support more "
|
||||||
|
"than six groups.\r\n\r\n"
|
||||||
|
"To remove this restriction, please choose Help -> "
|
||||||
|
"Website / Manual, and purchase a license.");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
Group g;
|
Group g;
|
||||||
ZERO(&g);
|
ZERO(&g);
|
||||||
g.visible = true;
|
g.visible = true;
|
||||||
|
|
|
@ -0,0 +1,64 @@
|
||||||
|
#!/usr/bin/perl
|
||||||
|
|
||||||
|
$POLY = 0xedb88320;
|
||||||
|
|
||||||
|
sub ProcessBit {
|
||||||
|
my ($bit) = @_;
|
||||||
|
|
||||||
|
my $topWasSet = ($shiftReg & (1 << 31));
|
||||||
|
|
||||||
|
$shiftReg <<= 1;
|
||||||
|
if($bit) {
|
||||||
|
$shiftReg |= 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if($topWasSet) {
|
||||||
|
$shiftReg ^= $POLY;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
sub ProcessByte {
|
||||||
|
my ($v) = @_;
|
||||||
|
for(0..7) {
|
||||||
|
ProcessBit($v & (1 << $_));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
sub ProcessString {
|
||||||
|
my ($str) = @_;
|
||||||
|
for (split //, $str) {
|
||||||
|
if($_ ne "\n" and $_ ne "\r") {
|
||||||
|
ProcessByte(ord($_));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
sub LicenseKey {
|
||||||
|
my @MAGIC = ( 203, 244, 134, 225, 45, 250, 70, 65,
|
||||||
|
224, 189, 35, 3, 228, 51, 77, 169, );
|
||||||
|
my $magic = join('', map { chr($_) } @MAGIC);
|
||||||
|
|
||||||
|
my ($line1, $line2, $users) = @_;
|
||||||
|
|
||||||
|
$shiftReg = 0;
|
||||||
|
ProcessString($line1);
|
||||||
|
ProcessString($line2);
|
||||||
|
ProcessString($users);
|
||||||
|
ProcessString($magic);
|
||||||
|
|
||||||
|
my $key = '±²³MechSketchLicense' . "\n";
|
||||||
|
$key .= $line1 . "\n";
|
||||||
|
$key .= $line2 . "\n";
|
||||||
|
$key .= $users . "\n";
|
||||||
|
$key .= sprintf("%08x\n", $shiftReg);
|
||||||
|
|
||||||
|
return $key;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
$line1 = "Jonathan Westhues";
|
||||||
|
$line2 = "";
|
||||||
|
$users = "single-user license";
|
||||||
|
|
||||||
|
print LicenseKey($line1, $line2, $users);
|
||||||
|
|
141
solvespace.cpp
141
solvespace.cpp
|
@ -2,7 +2,21 @@
|
||||||
|
|
||||||
SolveSpace SS;
|
SolveSpace SS;
|
||||||
|
|
||||||
|
void SolveSpace::CheckLicenseFromRegistry(void) {
|
||||||
|
// First, let's see if we're running licensed or free
|
||||||
|
CnfThawString(license.line1, sizeof(license.line1), "LicenseLine1");
|
||||||
|
CnfThawString(license.line2, sizeof(license.line2), "LicenseLine2");
|
||||||
|
CnfThawString(license.users, sizeof(license.users), "LicenseUsers");
|
||||||
|
license.key = CnfThawDWORD(0, "LicenseKey");
|
||||||
|
|
||||||
|
license.licensed =
|
||||||
|
LicenseValid(license.line1, license.line2, license.users, license.key);
|
||||||
|
}
|
||||||
|
|
||||||
void SolveSpace::Init(char *cmdLine) {
|
void SolveSpace::Init(char *cmdLine) {
|
||||||
|
CheckLicenseFromRegistry();
|
||||||
|
|
||||||
|
// Then, load the registry settings.
|
||||||
int i;
|
int i;
|
||||||
// Default list of colors for the model material
|
// Default list of colors for the model material
|
||||||
modelColor[0] = CnfThawDWORD(RGB(150, 150, 150), "ModelColor_0");
|
modelColor[0] = CnfThawDWORD(RGB(150, 150, 150), "ModelColor_0");
|
||||||
|
@ -431,14 +445,14 @@ void SolveSpace::MenuAnalyze(int id) {
|
||||||
case GraphicsWindow::MNU_STOP_TRACING: {
|
case GraphicsWindow::MNU_STOP_TRACING: {
|
||||||
char exportFile[MAX_PATH] = "";
|
char exportFile[MAX_PATH] = "";
|
||||||
if(GetSaveFile(exportFile, CSV_EXT, CSV_PATTERN)) {
|
if(GetSaveFile(exportFile, CSV_EXT, CSV_PATTERN)) {
|
||||||
FILE *f = fopen(exportFile, "w");
|
FILE *f = fopen(exportFile, "wb");
|
||||||
if(f) {
|
if(f) {
|
||||||
int i;
|
int i;
|
||||||
SContour *sc = &(SS.traced.path);
|
SContour *sc = &(SS.traced.path);
|
||||||
for(i = 0; i < sc->l.n; i++) {
|
for(i = 0; i < sc->l.n; i++) {
|
||||||
Vector p = sc->l.elem[i].p;
|
Vector p = sc->l.elem[i].p;
|
||||||
double s = SS.exportScale;
|
double s = SS.exportScale;
|
||||||
fprintf(f, "%.10f, %.10f, %.10f\n",
|
fprintf(f, "%.10f, %.10f, %.10f\r\n",
|
||||||
p.x/s, p.y/s, p.z/s);
|
p.x/s, p.y/s, p.z/s);
|
||||||
}
|
}
|
||||||
fclose(f);
|
fclose(f);
|
||||||
|
@ -457,3 +471,126 @@ void SolveSpace::MenuAnalyze(int id) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void SolveSpace::Crc::ProcessBit(int bit) {
|
||||||
|
bool topWasSet = ((shiftReg & (1 << 31)) != 0);
|
||||||
|
|
||||||
|
shiftReg <<= 1;
|
||||||
|
if(bit) {
|
||||||
|
shiftReg |= 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(topWasSet) {
|
||||||
|
shiftReg ^= POLY;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void SolveSpace::Crc::ProcessByte(BYTE b) {
|
||||||
|
int i;
|
||||||
|
for(i = 0; i < 8; i++) {
|
||||||
|
ProcessBit(b & (1 << i));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void SolveSpace::Crc::ProcessString(char *s) {
|
||||||
|
for(; *s; s++) {
|
||||||
|
if(*s != '\n' && *s != '\r') {
|
||||||
|
ProcessByte((BYTE)*s);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool SolveSpace::LicenseValid(char *line1, char *line2, char *users, DWORD key)
|
||||||
|
{
|
||||||
|
BYTE magic[17] = {
|
||||||
|
203, 244, 134, 225, 45, 250, 70, 65,
|
||||||
|
224, 189, 35, 3, 228, 51, 77, 169,
|
||||||
|
0
|
||||||
|
};
|
||||||
|
|
||||||
|
crc.shiftReg = 0;
|
||||||
|
crc.ProcessString(line1);
|
||||||
|
crc.ProcessString(line2);
|
||||||
|
crc.ProcessString(users);
|
||||||
|
crc.ProcessString((char *)magic);
|
||||||
|
|
||||||
|
return (key == crc.shiftReg);
|
||||||
|
}
|
||||||
|
|
||||||
|
void SolveSpace::CleanEol(char *in) {
|
||||||
|
char *s;
|
||||||
|
s = strchr(in, '\r');
|
||||||
|
if(s) *s = '\0';
|
||||||
|
s = strchr(in, '\n');
|
||||||
|
if(s) *s = '\0';
|
||||||
|
}
|
||||||
|
|
||||||
|
void SolveSpace::LoadLicenseFile(char *filename) {
|
||||||
|
FILE *f = fopen(filename, "rb");
|
||||||
|
if(!f) {
|
||||||
|
Error("Couldn't open file '%s'", filename);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
char buf[100];
|
||||||
|
fgets(buf, sizeof(buf), f);
|
||||||
|
char *str = "±²³MechSketchLicense";
|
||||||
|
if(memcmp(buf, str, strlen(str)) != 0) {
|
||||||
|
fclose(f);
|
||||||
|
Error("This is not a license file,");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
char line1[512], line2[512], users[512];
|
||||||
|
fgets(line1, sizeof(line1), f);
|
||||||
|
CleanEol(line1);
|
||||||
|
fgets(line2, sizeof(line2), f);
|
||||||
|
CleanEol(line2);
|
||||||
|
fgets(users, sizeof(users), f);
|
||||||
|
CleanEol(users);
|
||||||
|
|
||||||
|
fgets(buf, sizeof(buf), f);
|
||||||
|
DWORD key = 0;
|
||||||
|
sscanf(buf, "%x", &key);
|
||||||
|
|
||||||
|
if(LicenseValid(line1, line2, users, key)) {
|
||||||
|
// Install the new key
|
||||||
|
CnfFreezeString(line1, "LicenseLine1");
|
||||||
|
CnfFreezeString(line2, "LicenseLine2");
|
||||||
|
CnfFreezeString(users, "LicenseUsers");
|
||||||
|
CnfFreezeDWORD(key, "LicenseKey");
|
||||||
|
Message("License key successfully installed.");
|
||||||
|
|
||||||
|
// This updates our display in the text window to show that we're
|
||||||
|
// licensed now.
|
||||||
|
CheckLicenseFromRegistry();
|
||||||
|
SS.later.showTW = true;
|
||||||
|
} else {
|
||||||
|
Error("License key invalid.");
|
||||||
|
}
|
||||||
|
fclose(f);
|
||||||
|
}
|
||||||
|
|
||||||
|
void SolveSpace::MenuHelp(int id) {
|
||||||
|
switch(id) {
|
||||||
|
case GraphicsWindow::MNU_WEBSITE:
|
||||||
|
OpenWebsite("http://www.mechsketch.com/helpmenu");
|
||||||
|
break;
|
||||||
|
|
||||||
|
case GraphicsWindow::MNU_ABOUT:
|
||||||
|
Message("This is MechSketch version 0.1.\r\n\r\n"
|
||||||
|
"For more information, see http://www.mechsketch.com/\r\n\r\n"
|
||||||
|
"Built " __TIME__ " " __DATE__ ".\r\n\r\n"
|
||||||
|
"Copyright 2008 Jonathan Westhues, All Rights Reserved.");
|
||||||
|
break;
|
||||||
|
|
||||||
|
case GraphicsWindow::MNU_LICENSE: {
|
||||||
|
char licenseFile[MAX_PATH] = "";
|
||||||
|
if(GetOpenFile(licenseFile, LICENSE_EXT, LICENSE_PATTERN)) {
|
||||||
|
SS.LoadLicenseFile(licenseFile);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
default: oops();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
30
solvespace.h
30
solvespace.h
|
@ -64,11 +64,16 @@ int SaveFileYesNoCancel(void);
|
||||||
#define DXF_EXT "dxf"
|
#define DXF_EXT "dxf"
|
||||||
#define CSV_PATTERN "CSV File (*.csv)\0*.csv\0All Files (*)\0*\0\0"
|
#define CSV_PATTERN "CSV File (*.csv)\0*.csv\0All Files (*)\0*\0\0"
|
||||||
#define CSV_EXT "csv"
|
#define CSV_EXT "csv"
|
||||||
|
#define LICENSE_PATTERN \
|
||||||
|
"License File (*.license)\0*.license\0All Files (*)\0*\0\0"
|
||||||
|
#define LICENSE_EXT "license"
|
||||||
BOOL GetSaveFile(char *file, char *defExtension, char *selPattern);
|
BOOL GetSaveFile(char *file, char *defExtension, char *selPattern);
|
||||||
BOOL GetOpenFile(char *file, char *defExtension, char *selPattern);
|
BOOL GetOpenFile(char *file, char *defExtension, char *selPattern);
|
||||||
void GetAbsoluteFilename(char *file);
|
void GetAbsoluteFilename(char *file);
|
||||||
void LoadAllFontFiles(void);
|
void LoadAllFontFiles(void);
|
||||||
|
|
||||||
|
void OpenWebsite(char *url);
|
||||||
|
|
||||||
void CheckMenuById(int id, BOOL checked);
|
void CheckMenuById(int id, BOOL checked);
|
||||||
void EnableMenuById(int id, BOOL checked);
|
void EnableMenuById(int id, BOOL checked);
|
||||||
|
|
||||||
|
@ -92,6 +97,7 @@ void dbp(char *str, ...);
|
||||||
CO((tri).a), CO((tri).b), CO((tri).c))
|
CO((tri).a), CO((tri).b), CO((tri).c))
|
||||||
|
|
||||||
void SetWindowTitle(char *str);
|
void SetWindowTitle(char *str);
|
||||||
|
void Message(char *str, ...);
|
||||||
void Error(char *str, ...);
|
void Error(char *str, ...);
|
||||||
void ExitNow(void);
|
void ExitNow(void);
|
||||||
|
|
||||||
|
@ -376,6 +382,7 @@ public:
|
||||||
|
|
||||||
// The platform-dependent code calls this before entering the msg loop
|
// The platform-dependent code calls this before entering the msg loop
|
||||||
void Init(char *cmdLine);
|
void Init(char *cmdLine);
|
||||||
|
void CheckLicenseFromRegistry(void);
|
||||||
void Exit(void);
|
void Exit(void);
|
||||||
|
|
||||||
// File load/save routines, including the additional files that get
|
// File load/save routines, including the additional files that get
|
||||||
|
@ -464,6 +471,29 @@ public:
|
||||||
bool generateAll;
|
bool generateAll;
|
||||||
} later;
|
} later;
|
||||||
void DoLater(void);
|
void DoLater(void);
|
||||||
|
|
||||||
|
// For the licensing
|
||||||
|
class Crc {
|
||||||
|
public:
|
||||||
|
static const DWORD POLY = 0xedb88320;
|
||||||
|
DWORD shiftReg;
|
||||||
|
|
||||||
|
void ProcessBit(int bit);
|
||||||
|
void ProcessByte(BYTE b);
|
||||||
|
void ProcessString(char *s);
|
||||||
|
};
|
||||||
|
Crc crc;
|
||||||
|
struct {
|
||||||
|
bool licensed;
|
||||||
|
char line1[512];
|
||||||
|
char line2[512];
|
||||||
|
char users[512];
|
||||||
|
DWORD key;
|
||||||
|
} license;
|
||||||
|
static void MenuHelp(int id);
|
||||||
|
void CleanEol(char *s);
|
||||||
|
void LoadLicenseFile(char *filename);
|
||||||
|
bool LicenseValid(char *line1, char *line2, char *users, DWORD key);
|
||||||
};
|
};
|
||||||
|
|
||||||
extern SolveSpace SS;
|
extern SolveSpace SS;
|
||||||
|
|
|
@ -98,6 +98,9 @@ void TextWindow::ScreenHowGroupSolved(int link, DWORD v) {
|
||||||
void TextWindow::ScreenShowConfiguration(int link, DWORD v) {
|
void TextWindow::ScreenShowConfiguration(int link, DWORD v) {
|
||||||
SS.TW.GoToScreen(SCREEN_CONFIGURATION);
|
SS.TW.GoToScreen(SCREEN_CONFIGURATION);
|
||||||
}
|
}
|
||||||
|
void TextWindow::ScreenGoToWebsite(int link, DWORD v) {
|
||||||
|
OpenWebsite("http://www.mechsketch.com/txtlink");
|
||||||
|
}
|
||||||
void TextWindow::ShowListOfGroups(void) {
|
void TextWindow::ShowListOfGroups(void) {
|
||||||
Printf(true, "%Ftactv show ok group-name%E");
|
Printf(true, "%Ftactv show ok group-name%E");
|
||||||
int i;
|
int i;
|
||||||
|
@ -140,6 +143,22 @@ void TextWindow::ShowListOfGroups(void) {
|
||||||
&(TextWindow::ScreenShowGroupsSpecial));
|
&(TextWindow::ScreenShowGroupsSpecial));
|
||||||
Printf(false, " %Fl%Ls%fconfiguration%E",
|
Printf(false, " %Fl%Ls%fconfiguration%E",
|
||||||
&(TextWindow::ScreenShowConfiguration));
|
&(TextWindow::ScreenShowConfiguration));
|
||||||
|
|
||||||
|
// Show license info
|
||||||
|
Printf(false, "");
|
||||||
|
if(SS.license.licensed) {
|
||||||
|
Printf(false, "%FtLicensed to:");
|
||||||
|
Printf(false, "%Fg %s", SS.license.line1);
|
||||||
|
if(strlen(SS.license.line2)) {
|
||||||
|
Printf(false, "%Fg %s", SS.license.line2);
|
||||||
|
}
|
||||||
|
Printf(false, "%Fg %s", SS.license.users);
|
||||||
|
} else {
|
||||||
|
Printf(false, "%Fx*** THIS SOFTWARE IS NOT LICENSED ***");
|
||||||
|
Printf(false, "%Fx eval / non-commercial use only");
|
||||||
|
Printf(false, "%Fx buy at %Fl%f%Llhttp://www.mechsketch.com/%E",
|
||||||
|
&ScreenGoToWebsite);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -11,6 +11,7 @@ const TextWindow::Color TextWindow::fgColors[] = {
|
||||||
{ 'r', RGB( 0, 0, 0) },
|
{ 'r', RGB( 0, 0, 0) },
|
||||||
{ 'x', RGB(255, 20, 20) },
|
{ 'x', RGB(255, 20, 20) },
|
||||||
{ 'i', RGB( 0, 255, 255) },
|
{ 'i', RGB( 0, 255, 255) },
|
||||||
|
{ 'g', RGB(160, 160, 160) },
|
||||||
{ 0, 0 },
|
{ 0, 0 },
|
||||||
};
|
};
|
||||||
const TextWindow::Color TextWindow::bgColors[] = {
|
const TextWindow::Color TextWindow::bgColors[] = {
|
||||||
|
|
5
ui.h
5
ui.h
|
@ -130,6 +130,7 @@ public:
|
||||||
static void ScreenColor(int link, DWORD v);
|
static void ScreenColor(int link, DWORD v);
|
||||||
|
|
||||||
static void ScreenShowConfiguration(int link, DWORD v);
|
static void ScreenShowConfiguration(int link, DWORD v);
|
||||||
|
static void ScreenGoToWebsite(int link, DWORD v);
|
||||||
|
|
||||||
static void ScreenStepDimSteps(int link, DWORD v);
|
static void ScreenStepDimSteps(int link, DWORD v);
|
||||||
static void ScreenStepDimFinish(int link, DWORD v);
|
static void ScreenStepDimFinish(int link, DWORD v);
|
||||||
|
@ -224,6 +225,10 @@ public:
|
||||||
MNU_TRACE_PT,
|
MNU_TRACE_PT,
|
||||||
MNU_STOP_TRACING,
|
MNU_STOP_TRACING,
|
||||||
MNU_STEP_DIM,
|
MNU_STEP_DIM,
|
||||||
|
// Help,
|
||||||
|
MNU_LICENSE,
|
||||||
|
MNU_WEBSITE,
|
||||||
|
MNU_ABOUT,
|
||||||
} MenuId;
|
} MenuId;
|
||||||
typedef void MenuHandler(int id);
|
typedef void MenuHandler(int id);
|
||||||
typedef struct {
|
typedef struct {
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
#include <windows.h>
|
#include <windows.h>
|
||||||
|
#include <shellapi.h>
|
||||||
#include <commctrl.h>
|
#include <commctrl.h>
|
||||||
#include <commdlg.h>
|
#include <commdlg.h>
|
||||||
#include <gl/gl.h>
|
#include <gl/gl.h>
|
||||||
|
@ -55,25 +56,50 @@ void dbp(char *str, ...)
|
||||||
va_end(f);
|
va_end(f);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Error(char *str, ...)
|
|
||||||
|
static void DoMessageBox(char *str, va_list f, BOOL error)
|
||||||
{
|
{
|
||||||
va_list f;
|
char buf[1024*50];
|
||||||
char buf[1024];
|
|
||||||
va_start(f, str);
|
|
||||||
vsprintf(buf, str, f);
|
vsprintf(buf, str, f);
|
||||||
va_end(f);
|
|
||||||
|
|
||||||
EnableWindow(GraphicsWnd, FALSE);
|
EnableWindow(GraphicsWnd, FALSE);
|
||||||
EnableWindow(TextWnd, FALSE);
|
EnableWindow(TextWnd, FALSE);
|
||||||
|
|
||||||
|
int flags;
|
||||||
|
if(error) {
|
||||||
|
flags = MB_OK | MB_ICONERROR;
|
||||||
|
} else {
|
||||||
|
flags = MB_OK | MB_ICONINFORMATION;
|
||||||
|
}
|
||||||
HWND h = GetForegroundWindow();
|
HWND h = GetForegroundWindow();
|
||||||
MessageBox(h, buf, "SolveSpace Error", MB_OK | MB_ICONERROR);
|
MessageBox(h, buf, "SolveSpace", flags);
|
||||||
|
|
||||||
EnableWindow(TextWnd, TRUE);
|
EnableWindow(TextWnd, TRUE);
|
||||||
EnableWindow(GraphicsWnd, TRUE);
|
EnableWindow(GraphicsWnd, TRUE);
|
||||||
SetForegroundWindow(GraphicsWnd);
|
SetForegroundWindow(GraphicsWnd);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Error(char *str, ...)
|
||||||
|
{
|
||||||
|
va_list f;
|
||||||
|
va_start(f, str);
|
||||||
|
DoMessageBox(str, f, TRUE);
|
||||||
|
va_end(f);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Message(char *str, ...)
|
||||||
|
{
|
||||||
|
va_list f;
|
||||||
|
va_start(f, str);
|
||||||
|
DoMessageBox(str, f, FALSE);
|
||||||
|
va_end(f);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void OpenWebsite(char *url) {
|
||||||
|
ShellExecute(GraphicsWnd, "open", url, NULL, NULL, SW_SHOWNORMAL);
|
||||||
|
}
|
||||||
|
|
||||||
void ExitNow(void) {
|
void ExitNow(void) {
|
||||||
PostQuitMessage(0);
|
PostQuitMessage(0);
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue