2012-03-20 01:57:42 +01:00
# include "lc_global.h"
2011-09-07 23:06:51 +02:00
# include <stdio.h>
# include "lc_application.h"
# include "library.h"
# include "system.h"
# include "console.h"
# include "opengl.h"
# include "project.h"
# include "image.h"
// ----------------------------------------------------------------------------
// Global functions.
lcApplication * g_App ;
PiecesLibrary * lcGetPiecesLibrary ( )
{
LC_ASSERT ( g_App , " g_App not initialized. " ) ;
return g_App - > GetPiecesLibrary ( ) ;
}
Project * lcGetActiveProject ( )
{
LC_ASSERT ( g_App , " g_App not initialized. " ) ;
return g_App - > GetActiveProject ( ) ;
}
// ----------------------------------------------------------------------------
// lcApplication class.
lcApplication : : lcApplication ( )
{
m_ActiveProject = NULL ;
m_Library = NULL ;
}
lcApplication : : ~ lcApplication ( )
{
}
void lcApplication : : AddProject ( Project * project )
{
m_Projects . Add ( project ) ;
if ( m_ActiveProject = = NULL )
m_ActiveProject = project ;
}
bool lcApplication : : LoadPiecesLibrary ( const char * LibPath , const char * SysLibPath )
{
// Create an empty library.
if ( m_Library = = NULL )
m_Library = new PiecesLibrary ( ) ;
else
m_Library - > Unload ( ) ;
// Check if the user specified a library path in the command line.
if ( LibPath ! = NULL )
if ( m_Library - > Load ( LibPath ) )
return true ;
// Check for the LEOCAD_LIB environment variable.
char * EnvPath = getenv ( " LEOCAD_LIB " ) ;
if ( EnvPath ! = NULL )
if ( m_Library - > Load ( EnvPath ) )
return true ;
// Try the executable install path last.
if ( SysLibPath ! = NULL )
if ( m_Library - > Load ( SysLibPath ) )
return true ;
# ifdef LC_WINDOWS
SystemDoMessageBox ( " Cannot load pieces library. \n "
" Make sure that you have the PIECES.IDX file in the same "
" folder where you installed the program. " , LC_MB_OK | LC_MB_ICONERROR ) ;
# else
printf ( " Error: Cannot load pieces library. \n " ) ;
# endif
return false ;
}
2012-04-11 06:58:40 +02:00
void lcApplication : : ConvertPiecesLibrary ( const char * SrcPath , const char * DstPath )
{
ObjArray < String > FileList ;
PiecesLibrary Library ;
Library . SetPath ( DstPath ) ;
if ( ! Library . DeleteAllPieces ( ) )
{
printf ( " Error: Couldn't open library file for writing. " ) ; // TODO: replace printfs with a callback and progress dialog, then delete the duplicate code in libdlg.cpp
return ;
}
Sys_GetFileList ( SrcPath , FileList ) ;
if ( ! FileList . GetSize ( ) )
{
printf ( " Error: No files to import. " ) ;
return ;
}
char file1 [ LC_MAXPATH ] , file2 [ LC_MAXPATH ] ;
lcDiskFile DiskIdx , DiskBin ;
strcpy ( file1 , Library . GetLibraryPath ( ) ) ;
strcat ( file1 , " pieces.idx " ) ;
strcpy ( file2 , Library . GetLibraryPath ( ) ) ;
strcat ( file2 , " pieces.bin " ) ;
if ( ( ! DiskIdx . Open ( file1 , " rb " ) ) | | ( ! DiskBin . Open ( file2 , " rb " ) ) )
return ;
lcMemFile IdxFile1 , IdxFile2 , BinFile1 , BinFile2 ;
IdxFile1 . CopyFrom ( DiskIdx ) ;
BinFile1 . CopyFrom ( DiskBin ) ;
lcMemFile * NewIdx = & IdxFile1 ;
lcMemFile * NewBin = & BinFile1 ;
lcMemFile * OldIdx = & IdxFile2 ;
lcMemFile * OldBin = & BinFile2 ;
for ( int i = 0 ; i < FileList . GetSize ( ) ; i + + )
{
char * Name = FileList [ i ] ;
char * Slash = strrchr ( Name , ' \\ ' ) ;
if ( Slash > Name )
Name = Slash + 1 ;
Slash = strrchr ( Name , ' / ' ) ;
if ( Slash > Name )
Name = Slash + 1 ;
printf ( " Importing %s \n " , Name ) ;
lcMemFile * TmpFile ;
TmpFile = NewBin ;
NewBin = OldBin ;
OldBin = TmpFile ;
NewBin - > SetLength ( 0 ) ;
TmpFile = NewIdx ;
NewIdx = OldIdx ;
OldIdx = TmpFile ;
NewIdx - > SetLength ( 0 ) ;
lcGetPiecesLibrary ( ) - > ImportLDrawPiece ( FileList [ i ] , NewIdx , NewBin , OldIdx , OldBin ) ;
}
if ( ( ! DiskIdx . Open ( file1 , " wb " ) ) | | ( ! DiskBin . Open ( file2 , " wb " ) ) )
{
printf ( " Error: Couldn't open library file for writing. " ) ;
return ;
}
DiskIdx . CopyFrom ( * NewIdx ) ;
DiskBin . CopyFrom ( * NewBin ) ;
}
2011-09-07 23:06:51 +02:00
void lcApplication : : ParseIntegerArgument ( int * CurArg , int argc , char * argv [ ] , int * Value )
{
if ( argc > ( * CurArg + 1 ) )
{
( * CurArg ) + + ;
int val ;
if ( ( sscanf ( argv [ ( * CurArg ) ] , " %d " , & val ) = = 1 ) & & ( val > 0 ) )
* Value = val ;
else
console . PrintWarning ( " Invalid value specified for the %s argument. " , argv [ ( * CurArg ) - 1 ] ) ;
}
else
{
console . PrintWarning ( " Not enough parameters for the %s argument. " , argv [ ( * CurArg ) - 1 ] ) ;
}
}
void lcApplication : : ParseStringArgument ( int * CurArg , int argc , char * argv [ ] , char * * Value )
{
if ( argc > ( * CurArg + 1 ) )
{
( * CurArg ) + + ;
* Value = argv [ ( * CurArg ) ] ;
}
else
{
console . PrintWarning ( " No path specified after the %s argument. " , argv [ ( * CurArg ) - 1 ] ) ;
}
}
bool lcApplication : : Initialize ( int argc , char * argv [ ] , const char * SysLibPath )
{
// System setup parameters.
char * LibPath = NULL ;
char * GLPath = NULL ;
2012-04-11 06:58:40 +02:00
char * LDrawPath = NULL ;
2011-09-07 23:06:51 +02:00
// Image output options.
bool SaveImage = false ;
bool ImageAnimation = false ;
bool ImageInstructions = false ;
bool ImageHighlight = false ;
int ImageWidth = Sys_ProfileLoadInt ( " Default " , " Image Width " , 640 ) ;
int ImageHeight = Sys_ProfileLoadInt ( " Default " , " Image Height " , 480 ) ;
int ImageStart = 0 ;
int ImageEnd = 0 ;
char * ImageName = NULL ;
// File to open.
char * ProjectName = NULL ;
// Parse the command line arguments.
for ( int i = 1 ; i < argc ; i + + )
{
char * Param = argv [ i ] ;
if ( Param [ 0 ] = = ' - ' )
{
if ( strcmp ( Param , " --libgl " ) = = 0 )
{
ParseStringArgument ( & i , argc , argv , & GLPath ) ;
}
else if ( ( strcmp ( Param , " -l " ) = = 0 ) | | ( strcmp ( Param , " --libpath " ) = = 0 ) )
{
ParseStringArgument ( & i , argc , argv , & LibPath ) ;
}
2012-04-11 06:58:40 +02:00
else if ( strcmp ( Param , " --convert " ) = = 0 )
{
if ( argc > i + 2 )
{
ParseStringArgument ( & i , argc , argv , & LDrawPath ) ;
ParseStringArgument ( & i , argc , argv , & LibPath ) ;
ConvertPiecesLibrary ( LDrawPath , LibPath ) ;
}
else
{
printf ( " Not enough command line arguments. \n " ) ;
}
return false ;
}
2011-09-07 23:06:51 +02:00
else if ( ( strcmp ( Param , " -i " ) = = 0 ) | | ( strcmp ( Param , " --image " ) = = 0 ) )
{
SaveImage = true ;
if ( ( argc > ( i + 1 ) ) & & ( argv [ i + 1 ] [ 0 ] ! = ' - ' ) )
{
i + + ;
ImageName = argv [ i ] ;
}
}
else if ( ( strcmp ( Param , " -w " ) = = 0 ) | | ( strcmp ( Param , " --width " ) = = 0 ) )
{
ParseIntegerArgument ( & i , argc , argv , & ImageWidth ) ;
}
else if ( ( strcmp ( Param , " -h " ) = = 0 ) | | ( strcmp ( Param , " --height " ) = = 0 ) )
{
ParseIntegerArgument ( & i , argc , argv , & ImageHeight ) ;
}
else if ( ( strcmp ( Param , " -f " ) = = 0 ) | | ( strcmp ( Param , " --from " ) = = 0 ) )
{
ParseIntegerArgument ( & i , argc , argv , & ImageStart ) ;
}
else if ( ( strcmp ( Param , " -t " ) = = 0 ) | | ( strcmp ( Param , " --to " ) = = 0 ) )
{
ParseIntegerArgument ( & i , argc , argv , & ImageEnd ) ;
}
else if ( strcmp ( Param , " --animation " ) = = 0 )
ImageAnimation = true ;
else if ( strcmp ( Param , " --instructions " ) = = 0 )
ImageInstructions = true ;
else if ( strcmp ( Param , " --highlight " ) = = 0 )
ImageHighlight = true ;
else if ( ( strcmp ( Param , " -v " ) = = 0 ) | | ( strcmp ( Param , " --version " ) = = 0 ) )
{
printf ( " LeoCAD version " LC_VERSION_TEXT LC_VERSION_TAG " for " LC_VERSION_OSNAME " \n " ) ;
printf ( " Copyright (c) 1996-2006, BT Software \n " ) ;
printf ( " Compiled " __DATE__ " \n " ) ;
# ifdef LC_HAVE_JPEGLIB
printf ( " With JPEG support \n " ) ;
# else
printf ( " Without JPEG support \n " ) ;
# endif
# ifdef LC_HAVE_PNGLIB
printf ( " With PNG support \n " ) ;
# else
printf ( " Without PNG support \n " ) ;
# endif
return false ;
}
else if ( ( strcmp ( Param , " -? " ) = = 0 ) | | ( strcmp ( Param , " --help " ) = = 0 ) )
{
printf ( " Usage: leocad [options] [file] \n " ) ;
printf ( " [options] can be: \n " ) ;
printf ( " --libgl <path>: Searches for OpenGL libraries in path. \n " ) ;
2012-04-11 06:58:40 +02:00
printf ( " --libpath <path>: Loads the Pieces Library from path. \n " ) ;
printf ( " --convert <srcpath> <dstpath>: Generates Pieces Library from LDraw files. \n " ) ;
2011-09-07 23:06:51 +02:00
printf ( " -i, --image <outfile.ext>: Saves a picture in the format specified by ext. \n " ) ;
printf ( " -w, --width <width>: Sets the picture width. \n " ) ;
printf ( " -h, --height <height>: Sets the picture height. \n " ) ;
printf ( " -f, --from <time>: Sets the first frame or step to save pictures. \n " ) ;
printf ( " -t, --to <time>: Sets the last frame or step to save pictures. \n " ) ;
printf ( " --animation: Saves animations frames. \n " ) ;
printf ( " --instructions: Saves instructions steps. \n " ) ;
printf ( " --highlight: Highlight pieces in the steps they appear. \n " ) ;
printf ( " \n " ) ;
}
else
console . PrintWarning ( " Unknown parameter: %s \n " , Param ) ;
}
else
{
ProjectName = Param ;
}
}
// Initialize other systems.
if ( ! GL_Initialize ( GLPath ) )
return false ;
if ( ! LoadPiecesLibrary ( LibPath , SysLibPath ) )
return false ;
SystemInit ( ) ;
// Create a new project.
Project * project = new Project ( ) ;
AddProject ( project ) ;
// Load project.
if ( ProjectName & & project - > OpenProject ( ProjectName ) )
{
if ( ! SaveImage )
return true ;
// Check if there's a file name and it has an extension.
bool NeedExt = true ;
String FileName ;
if ( ! ImageName )
{
FileName = ProjectName ;
int i = FileName . ReverseFind ( ' . ' ) ;
if ( i ! = - 1 )
FileName [ i ] = 0 ;
}
else
{
FileName = ImageName ;
int i = FileName . ReverseFind ( ' . ' ) ;
String Ext ;
if ( i ! = - 1 )
{
Ext = FileName . Right ( FileName . GetLength ( ) - i ) ;
Ext . MakeLower ( ) ;
}
if ( ( Ext = = " bmp " ) | | ( Ext = = " gif " ) )
NeedExt = false ;
# ifdef LC_HAVE_JPEGLIB
else if ( ( Ext = = " jpg " ) | | ( Ext = = " jpeg " ) )
NeedExt = false ;
# endif
# ifdef LC_HAVE_PNGLIB
else if ( Ext = = " png " )
NeedExt = false ;
# endif
}
// Setup default options.
LC_IMAGE_OPTS ImageOptions ;
unsigned long image = Sys_ProfileLoadInt ( " Default " , " Image Options " , 1 | LC_IMAGE_TRANSPARENT ) ;
ImageOptions . quality = Sys_ProfileLoadInt ( " Default " , " JPEG Quality " , 70 ) ;
ImageOptions . interlaced = ( image & LC_IMAGE_PROGRESSIVE ) ! = 0 ;
ImageOptions . transparent = ( image & LC_IMAGE_TRANSPARENT ) ! = 0 ;
ImageOptions . truecolor = ( image & LC_IMAGE_HIGHCOLOR ) ! = 0 ;
ImageOptions . format = image & ~ ( LC_IMAGE_MASK ) ;
ImageOptions . background [ 0 ] = ( unsigned char ) ( project - > GetBackgroundColor ( ) [ 0 ] * 255 ) ;
ImageOptions . background [ 1 ] = ( unsigned char ) ( project - > GetBackgroundColor ( ) [ 1 ] * 255 ) ;
ImageOptions . background [ 2 ] = ( unsigned char ) ( project - > GetBackgroundColor ( ) [ 2 ] * 255 ) ;
// Append file extension if needed.
if ( NeedExt )
{
switch ( ImageOptions . format )
{
default :
case LC_IMAGE_BMP :
FileName + = " .bmp " ;
break ;
case LC_IMAGE_GIF :
FileName + = " .gif " ;
break ;
case LC_IMAGE_JPG :
FileName + = " .jpg " ;
break ;
case LC_IMAGE_PNG :
FileName + = " .png " ;
break ;
}
}
if ( ImageInstructions )
project - > SetAnimation ( false ) ;
else if ( ImageAnimation )
project - > SetAnimation ( true ) ;
if ( ImageEnd < ImageStart )
ImageEnd = ImageStart ;
else if ( ImageStart > ImageEnd )
ImageStart = ImageEnd ;
if ( ( ImageStart = = 0 ) & & ( ImageEnd = = 0 ) )
{
ImageStart = ImageEnd = project - > GetCurrentTime ( ) ;
}
else if ( ( ImageStart = = 0 ) & & ( ImageEnd ! = 0 ) )
{
ImageStart = ImageEnd ;
}
else if ( ( ImageStart ! = 0 ) & & ( ImageEnd = = 0 ) )
{
ImageEnd = ImageStart ;
}
if ( project - > IsAnimation ( ) )
{
if ( ImageStart > project - > GetTotalFrames ( ) )
ImageStart = project - > GetTotalFrames ( ) ;
if ( ImageEnd > project - > GetTotalFrames ( ) )
ImageEnd = project - > GetTotalFrames ( ) ;
}
else
{
if ( ImageStart > 255 )
ImageStart = 255 ;
if ( ImageEnd > 255 )
ImageEnd = 255 ;
}
Image * images = new Image [ ImageEnd - ImageStart + 1 ] ;
project - > CreateImages ( images , ImageWidth , ImageHeight , ImageStart , ImageEnd , ImageHighlight ) ;
for ( int i = 0 ; i < = ImageEnd - ImageStart ; i + + )
{
char idx [ 256 ] ;
String Frame ;
if ( ImageStart ! = ImageEnd )
{
sprintf ( idx , " %02d " , i + 1 ) ;
int Ext = FileName . ReverseFind ( ' . ' ) ;
Frame = FileName . Left ( Ext ) + idx + FileName . Right ( FileName . GetLength ( ) - Ext ) ;
}
else
Frame = FileName ;
images [ i ] . FileSave ( Frame , & ImageOptions ) ;
}
delete [ ] images ;
return false ;
}
else
{
if ( SaveImage )
return false ;
else
project - > OnNewDocument ( ) ;
}
return true ;
}
void lcApplication : : Shutdown ( )
{
for ( int i = 0 ; i < m_Projects . GetSize ( ) ; i + + )
{
Project * project = m_Projects [ i ] ;
project - > HandleNotify ( LC_ACTIVATE , 0 ) ;
delete project ;
}
delete m_Library ;
m_Library = NULL ;
GL_Shutdown ( ) ;
}