Merged qtest branch into trunk.

This commit is contained in:
leo 2013-08-09 04:57:18 +00:00
parent 3bb6b098c8
commit f11c97777a
307 changed files with 25195 additions and 26292 deletions

View file

@ -1,2 +0,0 @@
all:
gmake ${.MAKEFLAGS} ${.TARGETS}

204
Makefile
View file

@ -1,204 +0,0 @@
### ALL CONFIGURATION SHOULD BE IN CONFIG.MK, NOT HERE
include config.mk
### Module directories
MODULES := $(OSDIR) common
### Look for include files in each of the modules
CPPFLAGS += $(patsubst %,-I%,$(MODULES))
CPPFLAGS += -g -Wextra -Wall -Wno-unused-parameter -Wshadow
### Extra libraries if required
LIBS :=
### Each module will add to this
SRC :=
BIN := bin/leocad
OBJDIR := obj
ifeq ($(findstring $(MAKECMDGOALS), help config-help config clean veryclean source-tgz source-zip), )
-include $(OSDIR)/config.mk
endif
### Include the description for each module
include $(patsubst %,%/module.mk,$(MODULES))
### Determine the object files
OBJ := $(patsubst %.cpp,$(OBJDIR)/%.o,$(filter %.cpp,$(SRC)))
### Link the program
.PHONY: all static
all: $(BIN)
static: bin/leocad.static
bin/leocad: $(OBJ) bin Makefile
@echo Linking $@
@$(CXX) -o $@ $(OBJ) $(LIBS) $(LDFLAGS)
bin/leocad.static: $(OBJ) bin Makefile
$(CXX) -static -o $@ $(OBJ) $(LIBS) $(LDFLAGS)
bin:
@mkdir bin
obj:
@mkdir $(OBJDIR) $(addprefix $(OBJDIR)/,$(MODULES))
### Include the C/C++ include dependencies
ifeq ($(findstring $(MAKECMDGOALS), help config-help config clean veryclean source-tgz source-zip), )
-include $(OBJ:.o=.d)
endif
### Calculate C/C++ include dependencies
$(OBJDIR)/%.d: %.cpp obj $(OSDIR)/config.mk
@$(CXX) -MM -MT '$(patsubst %.d,%.o, $@)' $(CXXFLAGS) $(CPPFLAGS) -w $< > $@
@[ -s $@ ] || rm -f $@
### Main compiler rule
$(OBJDIR)/%.o: %.cpp obj $(OSDIR)/config.mk
@echo $<
@$(CXX) $(CXXFLAGS) $(CPPFLAGS) -c -o '$(patsubst %.cpp,%.o, $@)' $<
@[ -s $@ ] || rm -f $@
### Various cleaning functions
.PHONY: clean distclean veryclean spotless all
clean:
@[ ! -d $(OBJDIR) ] || find $(OBJDIR) -name \*.o | xargs rm -f
veryclean: clean
@rm -rf $(OBJDIR)
@rm -rf bin
@rm -rf arch $(OSDIR)/config.mk
distclean: veryclean
### Dependency stuff is done automatically, so these do nothing.
.PHONY: dep depend
### Help function
.PHONY: help
help:
@echo 'Possible Targets are:'
@echo ' help (this is it)'
@echo ' all'
@echo ' install'
@echo ' uninstall'
@echo ' binary'
@echo ' source'
@echo ' (binary and source can be called as'
@echo ' a -zip or -tgz variants)'
@echo ' clean'
@echo ' veryclean'
@echo
### Rules to make various packaging
.PHONY: binary binary-tgz source-zip source-tgz source install uninstall
arch:
mkdir arch
desktop: obj
@echo "[Desktop Entry]" > $(OBJDIR)/leocad.desktop
@echo "Version=1.0" >> $(OBJDIR)/leocad.desktop
@echo "Name=LeoCAD" >> $(OBJDIR)/leocad.desktop
@echo "Comment=Create virtual LEGO models" >> $(OBJDIR)/leocad.desktop
@echo "Comment[eo]=Kreu virtualajn LEGO-ajn modelojn" >> $(OBJDIR)/leocad.desktop
@echo "Comment[it]=Crea modelli LEGO virtuali" >> $(OBJDIR)/leocad.desktop
@echo "Comment[nb]=Lag virtuelle LEGO-modeller" >> $(OBJDIR)/leocad.desktop
@echo "Comment[pt_BR]=Criar modelos virtuais de LEGO" >> $(OBJDIR)/leocad.desktop
@echo "Exec=$(PREFIX)/bin/leocad %f" >> $(OBJDIR)/leocad.desktop
@echo "Terminal=false" >> $(OBJDIR)/leocad.desktop
@echo "Type=Application" >> $(OBJDIR)/leocad.desktop
@echo "Icon=$(PREFIX)/share/pixmaps/leocad.svg" >> $(OBJDIR)/leocad.desktop
@echo "MimeType=application/vnd.leocad;application/x-ldraw;application/x-multi-part-ldraw;application/x-ldlite;" >> $(OBJDIR)/leocad.desktop
@echo "Categories=Graphics;3DGraphics;Education;" >> $(OBJDIR)/leocad.desktop
@echo "Keywords=CAD;LEGO;LDraw;" >> $(OBJDIR)/leocad.desktop
install: $(BIN) install-data install-update
uninstall: uninstall-data install-update
install-data: desktop
@install -d $(DESTDIR)$(PREFIX)/bin
@install -c -m 0755 $(BIN) $(DESTDIR)$(PREFIX)/bin/
@install -d $(DESTDIR)$(PREFIX)/share/man/man1
@install -c -m 0644 docs/leocad.1 $(DESTDIR)$(PREFIX)/share/man/man1/
@install -d $(DESTDIR)$(PREFIX)/share/leocad
@install -c -m 0644 tools/icon/icon128.png $(DESTDIR)$(PREFIX)/share/leocad/icon.png
@install -d $(DESTDIR)$(PREFIX)/share/applications
@install -c -m 0644 $(OBJDIR)/leocad.desktop $(DESTDIR)$(PREFIX)/share/applications/
@install -d $(DESTDIR)$(PREFIX)/share/pixmaps
@install -c -m 0644 tools/icon/icon.svg $(DESTDIR)$(PREFIX)/share/pixmaps/leocad.svg
@install -d $(DESTDIR)$(PREFIX)/share/icons/hicolor/scalable/mimetypes/
@rm -f $(DESTDIR)$(PREFIX)/share/icons/hicolor/scalable/mimetypes/application-vnd.leocad.svg
@ln -s $(PREFIX)/share/pixmaps/leocad.svg $(DESTDIR)$(PREFIX)/share/icons/hicolor/scalable/mimetypes/application-vnd.leocad.svg
@install -d $(DESTDIR)$(PREFIX)/share/mime/packages
@install -c -m 0644 linux/leocad-mime.xml $(DESTDIR)$(PREFIX)/share/mime/packages/
uninstall-data:
@rm -f $(DESTDIR)$(PREFIX)/bin/$(BIN)
@rm -f $(DESTDIR)$(PREFIX)/share/man/man1/leocad.1
@rm -f $(DESTDIR)$(PREFIX)/share/leocad/icon.png
@rm -f $(DESTDIR)$(PREFIX)/share/applications/leocad.desktop
@rm -f $(DESTDIR)$(PREFIX)/share/pixmaps/leocad.svg
@rm -f $(DESTDIR)$(PREFIX)/share/icons/hicolor/scalable/mimetypes/application-vnd.leocad.svg
@rm -f $(DESTDIR)$(PREFIX)/share/mime/packages/leocad-mime.xml
install-update:
@if test -z "$(DESTDIR)"; then \
if which gtk-update-icon-cache>/dev/null 2>&1; then \
gtk-update-icon-cache -q -f -t $(DESTDIR)$(PREFIX)/share/icons/hicolor; \
fi; \
if which update-mime-database>/dev/null 2>&1; then \
update-mime-database $(DESTDIR)$(PREFIX)/share/mime/; \
fi; \
if which update-desktop-database>/dev/null 2>&1; then \
update-desktop-database; \
fi; \
fi
binary: binary-zip binary-tgz
binary-zip: arch/leocad-linux.zip
binary-tgz: arch/leocad-linux.tgz
source: source-tgz source-zip
source-tgz: arch/leocad-src.tgz
source-zip: arch/leocad-src.zip
### Create a directory with the files needed for a binary package
package-dir: arch all
mkdir leocad
cp bin/leocad leocad
cp CREDITS.txt leocad/CREDITS
cp README.txt leocad/README
cp docs/INSTALL.txt leocad/INSTALL
cp docs/LINUX.txt leocad/LINUX
cp docs/leocad.1 leocad
arch/leocad-linux.zip: package-dir
rm -f $@
zip -r $@ leocad
rm -rf leocad
arch/leocad-linux.tgz: package-dir
rm -f $@
tar -cvzf $@ leocad
rm -rf leocad
arch/leocad-src.tgz: veryclean arch
rm -f $@
( cd .. ; tar --exclude=leocad/arch/\* --exclude=.svn -cvzf leocad/$@ leocad )
arch/leocad-src.zip: veryclean arch
rm -f $@
( cd .. ; zip -r leocad/$@ leocad -x '*/arch/*' -x '*/.svn/*' -x '*~' -x '*/core' -x '*/.#*')

View file

@ -1 +0,0 @@
include ../generic.mk

0
common/array.cpp Executable file → Normal file
View file

15
common/array.h Executable file → Normal file
View file

@ -58,6 +58,21 @@ public:
void InsertAt(int Index, const T& Obj);
void Sort(LC_OBJARRAY_COMPARE_FUNC SortFunc, void* SortData);
ObjArray<T>& operator=(const ObjArray<T>& Array)
{
m_Length = Array.m_Length;
m_Alloc = Array.m_Alloc;
m_Grow = Array.m_Grow;
delete[] m_Data;
m_Data = new T[m_Alloc];
for (int i = 0; i < m_Length; i++)
m_Data[i] = Array.m_Data[i];
return *this;
}
T& operator [](int Index) const
{ return m_Data[Index]; }

View file

@ -1,40 +1,15 @@
#ifndef _BASEWND_H_
#define _BASEWND_H_
#include <string.h>
#include "defines.h"
#include "lc_math.h"
#include "array.h"
#include "project.h"
#include "lc_category.h"
#include "image.h"
#include "lc_shortcuts.h"
// FIXME: move this to another place
#ifdef WIN32
#include "stdafx.h"
typedef CWnd* BaseWndXID;
typedef struct
{
CWnd* wnd;
int index;
UINT command;
} BaseMenuItem;
#endif
#ifdef LC_LINUX
#include <gtk/gtk.h>
typedef GtkWidget* BaseWndXID;
typedef struct
{
GtkWidget* widget;
GtkAccelGroup* accel;
} BaseMenuItem;
#endif
#ifdef LC_MACOSX
typedef void* BaseWndXID;
typedef struct
{
void* Dummy;
} BaseMenuItem;
#endif
// =============================================================================
// Message Box constants
class Group;
#define LC_OK 1
#define LC_CANCEL 2
@ -59,44 +34,155 @@ typedef struct
#define LC_MB_TYPEMASK 0x00F
#define LC_MB_ICONMASK 0x0F0
// =============================================================================
enum LC_DIALOG_TYPE
{
LC_DIALOG_OPEN_PROJECT,
LC_DIALOG_SAVE_PROJECT,
LC_DIALOG_MERGE_PROJECT,
LC_DIALOG_SAVE_IMAGE,
LC_DIALOG_EXPORT_3DSTUDIO,
LC_DIALOG_EXPORT_BRICKLINK,
LC_DIALOG_EXPORT_CSV,
LC_DIALOG_EXPORT_HTML,
LC_DIALOG_EXPORT_POVRAY,
LC_DIALOG_EXPORT_WAVEFRONT,
LC_DIALOG_PROPERTIES,
LC_DIALOG_PRINT,
LC_DIALOG_FIND,
LC_DIALOG_SELECT_BY_NAME,
LC_DIALOG_MINIFIG,
LC_DIALOG_PIECE_ARRAY,
LC_DIALOG_PIECE_GROUP,
LC_DIALOG_EDIT_GROUPS,
LC_DIALOG_PREFERENCES,
LC_DIALOG_CHECK_UPDATES,
LC_DIALOG_ABOUT
};
class BaseWnd
struct lcImageDialogOptions
{
char FileName[LC_MAXPATH];
LC_IMAGE_FORMAT Format;
bool Transparent;
int Width;
int Height;
int Start;
int End;
};
struct lcHTMLDialogOptions
{
char PathName[LC_MAXPATH];
LC_IMAGE_FORMAT ImageFormat;
bool TransparentImages;
bool SinglePage;
bool IndexPage;
int StepImagesWidth;
int StepImagesHeight;
bool HighlightNewParts;
bool PartsListStep;
bool PartsListEnd;
bool PartsListImages;
int PartImagesColor;
int PartImagesWidth;
int PartImagesHeight;
};
struct lcPOVRayDialogOptions
{
char FileName[LC_MAXPATH];
char POVRayPath[LC_MAXPATH];
char LGEOPath[LC_MAXPATH];
bool Render;
};
struct lcPropertiesDialogOptions
{
const char* Title;
char Author[101];
char Description[101];
char Comments[256];
int BackgroundType;
lcVector3 SolidColor;
lcVector3 GradientColor1;
lcVector3 GradientColor2;
char BackgroundFileName[LC_MAXPATH];
bool BackgroundTile;
bool FogEnabled;
float FogDensity;
lcVector3 FogColor;
lcVector3 AmbientColor;
bool DrawFloor;
bool SetDefault;
ObjArray<lcPiecesUsedEntry> PartsUsed;
};
struct lcArrayDialogOptions
{
int Counts[3];
lcVector3 Offsets[3];
lcVector3 Rotations[3];
};
struct lcEditGroupsDialogOptions
{
PtrArray<Group> PieceParents;
PtrArray<Group> GroupParents;
};
struct lcSelectDialogOptions
{
ObjArray<bool> Selection;
};
struct lcPreferencesDialogOptions
{
char DefaultAuthor[101];
char ProjectsPath[LC_MAXPATH];
char LibraryPath[LC_MAXPATH];
int MouseSensitivity;
int CheckForUpdates;
lcuint32 Snap;
lcuint32 Detail;
float LineWidth;
int AASamples;
int GridSize;
ObjArray<lcLibraryCategory> Categories;
bool CategoriesModified;
bool CategoriesDefault;
lcKeyboardShortcuts KeyboardShortcuts;
bool ShortcutsModified;
bool ShortcutsDefault;
};
class lcBaseWindow
{
public:
BaseWnd (BaseWnd *parent, int menu_count);
virtual ~BaseWnd ();
lcBaseWindow()
{
mHandle = NULL;
}
int MessageBox (const char* text, const char* caption="LeoCAD", int flags=LC_MB_OK|LC_MB_ICONINFORMATION);
void BeginWait ();
void EndWait ();
void SetTitle (const char *title);
~lcBaseWindow()
{
}
void ShowMenuItem (int id, bool show);
void EnableMenuItem (int id, bool enable);
void CheckMenuItem (int id, bool check);
void SetMenuItemText (int id, const char *text);
bool DoDialog(LC_DIALOG_TYPE Type, void* Data);
BaseWndXID GetXID () const
{ return m_pXID; }
void SetXID (BaseWndXID id)
{ m_pXID = id; }
int DoMessageBox(const char* Text, int Flags = LC_MB_OK | LC_MB_ICONINFORMATION)
{
return DoMessageBox(Text, "LeoCAD", Flags);
}
#ifdef LC_LINUX
// FIXME: remove
operator GtkWidget* () const
{ return m_pXID; }
#endif
int DoMessageBox(const char* Text, const char* Caption = "LeoCAD", int Flags = LC_MB_OK | LC_MB_ICONINFORMATION);
BaseMenuItem* GetMenuItem (int id) const
{ return &m_pMenuItems[id]; }
void SetMenuItem (int id, BaseMenuItem* item)
{ memcpy (&m_pMenuItems[id], item, sizeof (BaseMenuItem)); }
protected:
BaseWnd* m_pParent;
BaseWndXID m_pXID;
BaseMenuItem* m_pMenuItems;
void* mHandle;
};
#endif // _BASEWND_H_

View file

@ -6,7 +6,6 @@
#include <math.h>
#include <float.h>
#include "opengl.h"
#include "globals.h"
#include "lc_file.h"
#include "camera.h"
#include "view.h"
@ -665,7 +664,7 @@ void Camera::LoadProjection(float fAspect)
void Camera::ZoomExtents(View* view, const lcVector3& Center, const lcVector3* Points, int NumPoints, unsigned short nTime, bool bAnimation, bool bAddKey)
{
int Viewport[4] = { 0, 0, view->GetWidth(), view->GetHeight() };
int Viewport[4] = { 0, 0, view->mWidth, view->mHeight };
float Aspect = (float)Viewport[2]/(float)Viewport[3];
@ -687,7 +686,7 @@ void Camera::ZoomExtents(View* view, const lcVector3& Center, const lcVector3* P
void Camera::ZoomRegion(View* view, float Left, float Right, float Bottom, float Top, unsigned short nTime, bool bAnimation, bool bAddKey)
{
int Viewport[4] = { 0, 0, view->GetWidth(), view->GetHeight() };
int Viewport[4] = { 0, 0, view->mWidth, view->mHeight };
float Aspect = (float)Viewport[2]/(float)Viewport[3];
const lcMatrix44& ModelView = mWorldView;
@ -781,7 +780,7 @@ void Camera::DoRotate(int dx, int dy, int mouse, unsigned short nTime, bool bAni
Z[1] = -Z[1];
dx = -dx;
}
lcMatrix44 YRot(lcVector4(Z[0], Z[1], 0.0f, 0.0f), lcVector4(-Z[1], Z[0], 0.0f, 0.0f), lcVector4(0.0f, 0.0f, 1.0f, 0.0f), lcVector4(0.0f, 0.0f, 0.0f, 1.0f));
lcMatrix44 transform = lcMul(lcMul(lcMul(lcMatrix44AffineInverse(YRot), lcMatrix44RotationY(0.1f * dy / (21 - mouse))), YRot), lcMatrix44RotationZ(-0.1f * dx / (21 - mouse)));

View file

@ -158,6 +158,8 @@ public:
void GetTileInfo(int* row, int* col, int* width, int* height);
bool EndTile();
char m_strName[81];
float m_fovy;
float m_zNear;
float m_zFar;
@ -174,7 +176,6 @@ protected:
CameraTarget* m_pTarget;
// Attributes
char m_strName[81];
unsigned char m_nState;
unsigned char m_nType;

0
common/curve.cpp Executable file → Normal file
View file

4
common/curve.h Executable file → Normal file
View file

@ -1,6 +1,6 @@
#ifndef _CURVE_H_
#define _CURVE_H_
#if 0
#include "object.h"
#include "opengl.h"
#include "array.h"
@ -123,5 +123,5 @@ class Curve : public Object
PtrArray<CurvePoint> m_Points;
};
#endif
#endif // _CURVE_H_

View file

@ -1,99 +1,33 @@
// Constant definitions.
//
#ifndef _DEFINES_H_
#define _DEFINES_H_
// Check for supported platforms.
#if !(defined(LC_WINDOWS) || defined(LC_LINUX) || defined(LC_MACOSX))
#error YOU NEED TO DEFINE YOUR OS
#endif
// ============================================================================
// Old defines (mostly deprecated).
// TODO: cleanup defines and remove this file
#ifdef LC_WINDOWS
#define LC_MAXPATH 260 //_MAX_PATH
#define KEY_SHIFT VK_SHIFT
#define KEY_CONTROL VK_CONTROL
#define KEY_ALT VK_MENU
#define KEY_ESCAPE VK_ESCAPE
#define KEY_TAB VK_TAB
#define KEY_INSERT VK_INSERT
#define KEY_DELETE VK_DELETE
#define KEY_UP VK_UP
#define KEY_DOWN VK_DOWN
#define KEY_LEFT VK_LEFT
#define KEY_RIGHT VK_RIGHT
#define KEY_PRIOR VK_PRIOR
#define KEY_NEXT VK_NEXT
#define KEY_PLUS VK_ADD
#define KEY_MINUS VK_SUBTRACT
#define isnan _isnan
#endif
#ifdef LC_LINUX
#include <unistd.h>
#ifdef LC_QT
#define LC_MAXPATH 1024//MAXPATHLEN //FILENAME_MAX
#define LC_MAXPATH 1024 //FILENAME_MAX
#define KEY_SHIFT 0x01
#define KEY_CONTROL 0x02
#define KEY_ALT 0x03
#define KEY_ESCAPE 0x04
#define KEY_TAB 0x05
#define KEY_INSERT 0x06
#define KEY_DELETE 0x07
#define KEY_UP 0x08
#define KEY_DOWN 0x09
#define KEY_LEFT 0x0A
#define KEY_RIGHT 0x0B
#define KEY_PRIOR 0x0C
#define KEY_NEXT 0x0D
#define KEY_PLUS '+'
#define KEY_MINUS '-'
#define KEY_CONTROL Qt::CTRL
#define KEY_ESCAPE Qt::Key_Escape
#define KEY_TAB Qt::Key_Tab
#ifndef WIN32
char* strupr(char* string);
char* strlwr(char* string);
int stricmp(const char* str1, const char* str2);
#endif
#ifdef LC_MACOSX
#include <sys/param.h>
#define LC_MAXPATH MAXPATHLEN //FILENAME_MAX
#define KEY_SHIFT 0x01
#define KEY_CONTROL 0x02
#define KEY_ESCAPE 0x03
#define KEY_TAB 0x04
#define KEY_INSERT 0x05
#define KEY_DELETE 0x06
#define KEY_UP 0x07
#define KEY_DOWN 0x08
#define KEY_LEFT 0x09
#define KEY_RIGHT 0x0A
#define KEY_PRIOR 0x0B
#define KEY_NEXT 0x0C
#define KEY_PLUS '+'
#define KEY_MINUS '-'
char* strupr(char* string);
char* strlwr(char* string);
int stricmp(const char* str1, const char* str2);
#endif
/////////////////////////////////////////////////////////////////////////////
// LeoCAD constants
#ifndef LC_WINDOWS
#define RGB(r, g, b) ((unsigned long)(((unsigned char) (r) | ((unsigned short) (g) << 8))|(((unsigned long) (unsigned char) (b)) << 16)))
#endif
#define FLOATRGB(f) RGB(f[0]*255, f[1]*255, f[2]*255)
#define LC_FOURCC(ch0, ch1, ch2, ch3) (lcuint32)((lcuint32)(lcuint8)(ch0) | ((lcuint32)(lcuint8)(ch1) << 8) | \
((lcuint32)(lcuint8)(ch2) << 16) | ((lcuint32)(lcuint8)(ch3) << 24 ))
@ -101,57 +35,6 @@ int stricmp(const char* str1, const char* str2);
#define LC_STR_VERSION "LeoCAD 0.7 Project\0\0" // char[20]
//#define DET_BACKFACES 0x00001 // Draw backfaces
//#define DET_DEPTH 0x00002 // Enable depth test
//#define DET_CLEAR 0x00004 // Use clear colors
#define LC_DET_LIGHTING 0x00008 // Lighting
#define LC_DET_SMOOTH 0x00010 // Smooth shading
//#define DET_STUDS 0x00020 // Draw studs
//#define DET_WIREFRAME 0x00040 // Wireframe
//#define LC_DET_ANTIALIAS 0x00080 // Turn on anti-aliasing
#define LC_DET_BRICKEDGES 0x00100 // Draw lines
//#define LC_DET_DITHER 0x00200 // Enable dithering
//#define LC_DET_BOX_FILL 0x00400 // Filled boxes
//#define LC_DET_HIDDEN_LINE 0x00800 // Remove hidden lines
//#define DET_STUDS_BOX 0x01000 // Draw studs as boxes
//#define LC_DET_LINEAR 0x02000 // Linear filtering
#define LC_DET_FAST 0x04000 // Fast rendering (boxes)
//#define LC_DET_BACKGROUND 0x08000 // Background rendering
//#define LC_DET_SCREENDOOR 0x10000 // No alpha blending
#define LC_DRAW_AXIS 0x0001 // Orientation icon
#define LC_DRAW_GRID 0x0002 // Grid
#define LC_DRAW_SNAP_A 0x0004 // Snap Angle
#define LC_DRAW_SNAP_X 0x0008 // Snap X
#define LC_DRAW_SNAP_Y 0x0010 // Snap Y
#define LC_DRAW_SNAP_Z 0x0020 // Snap Z
#define LC_DRAW_SNAP_XYZ (LC_DRAW_SNAP_X | LC_DRAW_SNAP_Y | LC_DRAW_SNAP_Z)
#define LC_DRAW_GLOBAL_SNAP 0x0040 // Don't allow relative snap.
//#define LC_DRAW_MOVE 0x0080 // Switch to move after insert
#define LC_DRAW_LOCK_X 0x0100 // Lock X
#define LC_DRAW_LOCK_Y 0x0200 // Lock Y
#define LC_DRAW_LOCK_Z 0x0400 // Lock Z
#define LC_DRAW_LOCK_XYZ (LC_DRAW_LOCK_X | LC_DRAW_LOCK_Y | LC_DRAW_LOCK_Z)
#define LC_DRAW_MOVEAXIS 0x0800 // Move on fixed axis
//#define LC_DRAW_PREVIEW 0x1000 // Show piece position
#define LC_DRAW_CM_UNITS 0x2000 // Use centimeters
//#define LC_DRAW_3DMOUSE 0x4000 // Mouse moves in all directions
// #define RENDER_FAST 0x001
// #define RENDER_BACKGROUND 0x002
#define LC_SCENE_FOG 0x004 // Enable fog
// #define RENDER_FOG_BG 0x008 // Use bg color for fog
#define LC_SCENE_BG 0x010 // Draw bg image
// #define RENDER_BG_FAST 0x020
#define LC_SCENE_BG_TILE 0x040 // Tile bg image
#define LC_SCENE_FLOOR 0x080 // Render floor
#define LC_SCENE_GRADIENT 0x100 // Draw gradient
#define LC_TERRAIN_FLAT 0x01 // Flat terrain
#define LC_TERRAIN_TEXTURE 0x02 // Use texture
#define LC_TERRAIN_SMOOTH 0x04 // Smooth shading
#define LC_AUTOSAVE_FLAG 0x100000 // Enable auto-saving
#define LC_SEL_NO_PIECES 0x001 // No pieces in the project
@ -165,26 +48,4 @@ int stricmp(const char* str1, const char* str2);
#define LC_SEL_FOCUSGROUP 0x200 // focused piece is grouped
#define LC_SEL_CANGROUP 0x400 // can make a new group
// Image Options
#define LC_IMAGE_PROGRESSIVE 0x1000
#define LC_IMAGE_TRANSPARENT 0x2000
#define LC_IMAGE_HIGHCOLOR 0x4000
#define LC_IMAGE_MASK 0x7000
// HTML export options
#define LC_HTML_SINGLEPAGE 0x01
#define LC_HTML_INDEX 0x02
#define LC_HTML_IMAGES 0x04
#define LC_HTML_LISTEND 0x08
#define LC_HTML_LISTSTEP 0x10
#define LC_HTML_HIGHLIGHT 0x20
//#define LC_HTML_HTMLEXT 0x40
#define LC_HTML_LISTID 0x80
// Piece library update
#define LC_UPDATE_DELETE 0x00
#define LC_UPDATE_DESCRIPTION 0x01
#define LC_UPDATE_DRAWINFO 0x02
#define LC_UPDATE_NEWPIECE 0x04
#endif // _DEFINES_H_

View file

@ -1,10 +0,0 @@
//
// Global variables common to all platforms.
//
#include "lc_global.h"
#include <stdlib.h>
#include "globals.h"
Messenger* messenger;
MainWnd* main_window;

View file

@ -1,12 +0,0 @@
#ifndef _GLOBALS_H_
#define _GLOBALS_H_
#include "console.h"
class Messenger;
extern Messenger* messenger;
class MainWnd;
extern MainWnd* main_window;
#endif // _GLOBALS_H_

View file

@ -1,6 +1,8 @@
#ifndef _GROUP_H_
#define _GROUP_H_
#define LC_MAX_GROUP_NAME 64
class Group
{
public:
@ -18,7 +20,7 @@ public:
void FileLoad(lcFile* file);
void FileSave(lcFile* file, Group* pGroups);
char m_strName[65];
char m_strName[LC_MAX_GROUP_NAME + 1];
float m_fCenter[3];
};

View file

@ -1,493 +0,0 @@
#include "lc_global.h"
#include <stdio.h>
#include <stdlib.h>
#include "quant.h"
#include "image.h"
#include "lc_file.h"
// ========================================================
bool Image::LoadBMP(lcFile& file)
{
lcint32 bmWidth, bmHeight;
lcuint16 bmPlanes, bmBitsPixel;
lcuint8 m1, m2;
typedef struct {
unsigned char rgbBlue;
unsigned char rgbGreen;
unsigned char rgbRed;
unsigned char rgbReserved;
} RGBQUAD;
lcint16 res1,res2;
lcint32 filesize, pixoff;
lcint32 bmisize, compression;
lcint32 xscale, yscale;
lcint32 colors, impcol, rc;
lcuint32 sizeimage, m_bytesRead = 0;
FreeData ();
if (file.ReadU8(&m1, 1) != 1)
return false;
m_bytesRead++;
if (file.ReadU8(&m2, 1) != 1)
return false;
m_bytesRead++;
if ((m1 != 'B') || (m2 != 'M'))
return false;
rc = file.ReadS32(&filesize, 1); m_bytesRead+=4;
if (rc != 1) { return false; }
rc = file.ReadS16(&res1, 1); m_bytesRead+=2;
if (rc != 1) { return false; }
rc = file.ReadS16(&res2, 1); m_bytesRead+=2;
if (rc != 1) { return false; }
rc = file.ReadS32(&pixoff, 1); m_bytesRead+=4;
if (rc != 1) { return false; }
rc = file.ReadS32(&bmisize, 1); m_bytesRead+=4;
if (rc != 1) { return false; }
rc = file.ReadS32(&bmWidth, 1); m_bytesRead+=4;
if (rc != 1) { return false; }
rc = file.ReadS32(&bmHeight, 1); m_bytesRead+=4;
if (rc != 1) { return false; }
rc = file.ReadU16(&bmPlanes, 1); m_bytesRead+=2;
if (rc != 1) { return false; }
rc = file.ReadU16(&bmBitsPixel, 1); m_bytesRead+=2;
if (rc != 1) { return false; }
rc = file.ReadS32(&compression, 1); m_bytesRead+=4;
if (rc != 1) { return false; }
rc = file.ReadU32(&sizeimage, 1); m_bytesRead+=4;
if (rc != 1) {return false; }
rc = file.ReadS32(&xscale, 1); m_bytesRead+=4;
if (rc != 1) { return false; }
rc = file.ReadS32(&yscale, 1); m_bytesRead+=4;
if (rc != 1) { return false; }
rc = file.ReadS32(&colors, 1); m_bytesRead+=4;
if (rc != 1) { return false; }
rc = file.ReadS32(&impcol, 1); m_bytesRead+=4;
if (rc != 1) { return false; }
if (colors == 0)
colors = 1 << bmBitsPixel;
RGBQUAD *colormap = NULL;
if (bmBitsPixel != 24)
{
colormap = new RGBQUAD[colors];
if (colormap == NULL)
return false;
int i;
for (i = 0; i < colors; i++)
{
unsigned char r ,g, b, dummy;
rc = file.ReadU8(&b, 1);
m_bytesRead++;
if (rc!=1)
{
delete [] colormap;
return false;
}
rc = file.ReadU8(&g, 1);
m_bytesRead++;
if (rc!=1)
{
delete [] colormap;
return false;
}
rc = file.ReadU8(&r, 1);
m_bytesRead++;
if (rc != 1)
{
delete [] colormap;
return false;
}
rc = file.ReadU8(&dummy, 1);
m_bytesRead++;
if (rc != 1)
{
delete [] colormap;
return false;
}
colormap[i].rgbRed = r;
colormap[i].rgbGreen = g;
colormap[i].rgbBlue = b;
}
}
if ((long)m_bytesRead > pixoff)
{
delete [] colormap;
return false;
}
while ((long)m_bytesRead < pixoff)
{
lcuint8 dummy;
file.ReadU8(&dummy, 1);
m_bytesRead++;
}
int w = bmWidth;
int h = bmHeight;
// set the output params
m_pData = (unsigned char*)malloc (w*h*3);
long row_size = w * 3;
if (m_pData != NULL)
{
m_nWidth = w;
m_nHeight = h;
m_bAlpha = false;
unsigned char* outbuf = m_pData;
long row = 0;
long rowOffset = 0;
if (compression == 0) // BI_RGB
{
// read rows in reverse order
for (row=bmHeight-1;row>=0;row--)
{
// which row are we working on?
rowOffset = (long unsigned)row*row_size;
if (bmBitsPixel == 24)
{
for (int col=0;col<w;col++)
{
long offset = col * 3;
lcuint8 pixel[3];
if (file.ReadU8(pixel, 3) ==3)
{
// we swap red and blue here
*(outbuf + rowOffset + offset + 0) = pixel[2]; // r
*(outbuf + rowOffset + offset + 1) = pixel[1]; // g
*(outbuf + rowOffset + offset + 2) = pixel[0]; // b
}
}
m_bytesRead += row_size;
// read DWORD padding
while ((m_bytesRead-pixoff)&3)
{
lcuint8 dummy;
if (file.ReadU8(&dummy, 1) != 1)
{
FreeData ();
return false;
}
m_bytesRead++;
}
}
else
{
// pixels are packed as 1 , 4 or 8 bit vals. need to unpack them
int bit_count = 0;
unsigned long mask = (1 << bmBitsPixel) - 1;
unsigned char inbyte = 0;
for (int col=0;col<w;col++)
{
int pix = 0;
// if we need another byte
if (bit_count <= 0)
{
bit_count = 8;
if (file.ReadU8(&inbyte, 1) != 1)
{
FreeData ();
delete [] colormap;
return false;
}
m_bytesRead++;
}
// keep track of where we are in the bytes
bit_count -= bmBitsPixel;
pix = ( inbyte >> bit_count) & mask;
// lookup the color from the colormap - stuff it in our buffer
// swap red and blue
*(outbuf + rowOffset + col * 3 + 2) = colormap[pix].rgbBlue;
*(outbuf + rowOffset + col * 3 + 1) = colormap[pix].rgbGreen;
*(outbuf + rowOffset + col * 3 + 0) = colormap[pix].rgbRed;
}
// read DWORD padding
while ((m_bytesRead-pixoff)&3)
{
lcuint8 dummy;
if (file.ReadU8(&dummy, 1) != 1)
{
FreeData ();
if (colormap)
delete [] colormap;
return false;
}
m_bytesRead++;
}
}
}
}
else
{
int i, x = 0;
unsigned char c, c1 = 0, *pp;
row = 0;
pp = outbuf + (bmHeight-1)*bmWidth*3;
if (bmBitsPixel == 8)
{
while (row < bmHeight)
{
c = file.ReadU8();
if (c)
{
// encoded mode
c1 = file.ReadU8();
for (i = 0; i < c; x++, i++)
{
*pp = colormap[c1].rgbRed; pp++;
*pp = colormap[c1].rgbGreen; pp++;
*pp = colormap[c1].rgbBlue; pp++;
}
}
else
{
// c==0x00, escape codes
c = file.ReadU8();
if (c == 0x00) // end of line
{
row++;
x = 0;
pp = outbuf + (bmHeight-row-1)*bmWidth*3;
}
else if (c == 0x01)
break; // end of pic
else if (c == 0x02) // delta
{
c = file.ReadU8();
x += c;
c = file.ReadU8();
row += c;
pp = outbuf + x*3 + (bmHeight-row-1)*bmWidth*3;
}
else // absolute mode
{
for (i = 0; i < c; x++, i++)
{
c1 = file.ReadU8();
*pp = colormap[c1].rgbRed; pp++;
*pp = colormap[c1].rgbGreen; pp++;
*pp = colormap[c1].rgbBlue; pp++;
}
if (c & 1)
file.ReadU8(); // odd length run: read an extra pad byte
}
}
}
}
else if (bmBitsPixel == 4)
{
while (row < bmHeight)
{
c = file.ReadU8();
if (c)
{
// encoded mode
c1 = file.ReadU8();
for (i = 0; i < c; x++, i++)
{
*pp = colormap[(i&1) ? (c1 & 0x0f) : ((c1>>4)&0x0f)].rgbRed; pp++;
*pp = colormap[(i&1) ? (c1 & 0x0f) : ((c1>>4)&0x0f)].rgbGreen; pp++;
*pp = colormap[(i&1) ? (c1 & 0x0f) : ((c1>>4)&0x0f)].rgbBlue; pp++;
}
}
else
{
// c==0x00, escape codes
c = file.ReadU8();
if (c == 0x00) // end of line
{
row++;
x = 0;
pp = outbuf + (bmHeight-row-1)*bmWidth*3;
}
else if (c == 0x01)
break; // end of pic
else if (c == 0x02) // delta
{
c = file.ReadU8();
x += c;
c = file.ReadU8();
row += c;
pp = outbuf + x*3 + (bmHeight-row-1)*bmWidth*3;
}
else // absolute mode
{
for (i = 0; i < c; x++, i++)
{
if ((i&1) == 0)
c1 = file.ReadU8();
*pp = colormap[(i&1) ? (c1 & 0x0f) : ((c1>>4)&0x0f)].rgbRed; pp++;
*pp = colormap[(i&1) ? (c1 & 0x0f) : ((c1>>4)&0x0f)].rgbGreen; pp++;
*pp = colormap[(i&1) ? (c1 & 0x0f) : ((c1>>4)&0x0f)].rgbBlue; pp++;
}
if (((c&3) == 1) || ((c&3) == 2))
file.ReadU8(); // odd length run: read an extra pad byte
}
}
}
}
}
if (colormap)
delete [] colormap;
}
return true;
}
// ========================================================
bool Image::SaveBMP(lcFile& file, bool quantize) const
{
lcuint16 bits;
lcuint32 cmap, bfSize;
lcuint8 pal[3][256], *colormappedbuffer = NULL;
if (quantize)
{
colormappedbuffer = (unsigned char*)malloc(m_nWidth*m_nHeight);
dl1quant (m_pData, colormappedbuffer, m_nWidth, m_nHeight, 256, true, pal);
bits = 8;
cmap = 256;
bfSize = 1078 + m_nWidth*m_nHeight;
}
else
{
bits = 24;
cmap = 0;
bfSize = 54 + m_nWidth*m_nHeight*3;
}
long byteswritten = 0;
lcuint32 pixoff = 54 + cmap*4;
lcuint16 res = 0;
lcuint8 m1 ='B', m2 ='M';
file.WriteU8(&m1, 1); byteswritten++; // B
file.WriteU8(&m2, 1); byteswritten++; // M
file.WriteU32(&bfSize, 1); byteswritten+=4;// bfSize
file.WriteU16(&res, 1); byteswritten+=2;// bfReserved1
file.WriteU16(&res, 1); byteswritten+=2;// bfReserved2
file.WriteU32(&pixoff, 1); byteswritten+=4;// bfOffBits
lcuint32 biSize = 40, compress = 0, size = 0;
lcuint32 width = m_nWidth, height = m_nHeight, pixels = 0;
lcuint16 planes = 1;
file.WriteU32(&biSize, 1); byteswritten+=4;// biSize
file.WriteU32(&width, 1); byteswritten+=4;// biWidth
file.WriteU32(&height, 1); byteswritten+=4;// biHeight
file.WriteU16(&planes, 1); byteswritten+=2;// biPlanes
file.WriteU16(&bits, 1); byteswritten+=2;// biBitCount
file.WriteU32(&compress, 1); byteswritten+=4;// biCompression
file.WriteU32(&size, 1); byteswritten+=4;// biSizeImage
file.WriteU32(&pixels, 1); byteswritten+=4;// biXPelsPerMeter
file.WriteU32(&pixels, 1); byteswritten+=4;// biYPelsPerMeter
file.WriteU32(&cmap, 1); byteswritten+=4;// biClrUsed
file.WriteU32(&cmap, 1); byteswritten+=4;// biClrImportant
if (quantize)
{
for (int i = 0; i < 256; i++)
{
file.WriteU8(pal[2][i]);
file.WriteU8(pal[1][i]);
file.WriteU8(pal[0][i]);
file.WriteU8(0); // dummy
}
for (int row = 0; row < m_nHeight; row++)
{
int pixbuf = 0;
for (int col = 0; col < m_nWidth; col++)
{
int offset = (m_nHeight-row-1) * width + col; // offset into our color-mapped RGB buffer
unsigned char pval = *(colormappedbuffer + offset);
pixbuf = (pixbuf << 8) | pval;
file.WriteU8(pixbuf);
pixbuf = 0;
byteswritten++;
}
// DWORD align
while ((byteswritten - pixoff) & 3)
{
file.WriteU8(0);
byteswritten++;
}
}
free(colormappedbuffer);
}
else
{
unsigned long widthDW = (((m_nWidth*24) + 31) / 32 * 4);
long row, row_size = m_nWidth*3;
for (row = 0; row < m_nHeight; row++)
{
unsigned char* buf = m_pData+(m_nHeight-row-1)*row_size;
// write a row
for (int col = 0; col < row_size; col += 3)
{
file.WriteU8(buf[col+2]);
file.WriteU8(buf[col+1]);
file.WriteU8(buf[col]);
}
byteswritten += row_size;
for (unsigned long count = row_size; count < widthDW; count++)
{
file.WriteU8(0); // dummy
byteswritten++;
}
}
}
return true;
}

View file

@ -1,374 +0,0 @@
#include "lc_global.h"
#include <stdlib.h>
#include "image.h"
#include "lc_file.h"
#ifdef LC_HAVE_PNGLIB
#include <png.h>
#define alpha_composite(composite, fg, alpha, bg) { \
unsigned short temp = ((unsigned short)(fg)*(unsigned short)(alpha) + \
(unsigned short)(bg)*(unsigned short)(255 - (unsigned short)(alpha)) + (unsigned short)128); \
(composite) = (unsigned char)((temp + (temp >> 8)) >> 8); \
}
// =============================================================================
static void user_read_fn(png_structp png_ptr, png_bytep data, png_size_t length)
{
png_size_t check;
// Read() returns 0 on error, so it is OK to store this in a png_size_t
// instead of an int, which is what Read() actually returns.
check = (png_size_t)((lcFile*)png_get_io_ptr(png_ptr))->ReadBuffer(data, length);
if (check != length)
png_error(png_ptr, "Read Error");
}
bool Image::LoadPNG(lcFile& file)
{
unsigned char sig[8], red, green, blue;
unsigned char *image_data = NULL;
unsigned char *src, *dest;
unsigned char r, g, b, a;
unsigned long i, row;
unsigned long image_rowbytes;
png_color_16p pBackground;
png_structp png_ptr = NULL;
png_infop info_ptr = NULL;
png_uint_32 width, height;
png_bytepp row_pointers = NULL;
int bit_depth, color_type;
int image_channels;
double gamma;
FreeData();
file.ReadBuffer(sig, 8);
if (!png_check_sig(sig, 8))
return false; // bad signature
png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL);
if (!png_ptr)
return false; // out of memory
info_ptr = png_create_info_struct(png_ptr);
if (!info_ptr)
{
png_destroy_read_struct(&png_ptr, NULL, NULL);
return false; // out of memory
}
if (setjmp(png_jmpbuf(png_ptr)))
{
png_destroy_read_struct(&png_ptr, &info_ptr, NULL);
return false;
}
png_set_read_fn(png_ptr, (void*)&file, user_read_fn);
// png_init_io(png_ptr, f);
png_set_sig_bytes(png_ptr, 8); // we already read the 8 signature bytes
png_read_info(png_ptr, info_ptr); // read all PNG info up to image data
png_get_IHDR(png_ptr, info_ptr, &width, &height, &bit_depth, &color_type, NULL, NULL, NULL);
if (setjmp(png_jmpbuf(png_ptr)))
{
png_destroy_read_struct(&png_ptr, &info_ptr, NULL);
return false;
}
if (png_get_valid(png_ptr, info_ptr, PNG_INFO_bKGD))
{
png_get_bKGD(png_ptr, info_ptr, &pBackground);
if (setjmp(png_jmpbuf(png_ptr)))
{
png_destroy_read_struct(&png_ptr, &info_ptr, NULL);
return false;
}
// however, it always returns the raw bKGD data, regardless of any
// bit-depth transformations, so check depth and adjust if necessary
if (bit_depth == 16)
{
red = pBackground->red >> 8;
green = pBackground->green >> 8;
blue = pBackground->blue >> 8;
}
else if (color_type == PNG_COLOR_TYPE_GRAY && bit_depth < 8)
{
if (bit_depth == 1)
red = green = blue = pBackground->gray? 255 : 0;
else if (bit_depth == 2)
red = green = blue = (255/3) * pBackground->gray;
else // bit_depth == 4
red = green = blue = (255/15) * pBackground->gray;
}
else
{
red = (unsigned char)pBackground->red;
green = (unsigned char)pBackground->green;
blue = (unsigned char)pBackground->blue;
}
}
else
{
if (setjmp(png_jmpbuf(png_ptr)))
{
png_destroy_read_struct(&png_ptr, &info_ptr, NULL);
return false;
}
red = green = blue = 0;
}
// expand palette images to RGB, low-bit-depth grayscale images to 8 bits,
// transparency chunks to full alpha channel; strip 16-bit-per-sample
// images to 8 bits per sample; and convert grayscale to RGB[A]
if (color_type == PNG_COLOR_TYPE_PALETTE)
png_set_expand(png_ptr);
if (color_type == PNG_COLOR_TYPE_GRAY && bit_depth < 8)
png_set_expand(png_ptr);
if (png_get_valid(png_ptr, info_ptr, PNG_INFO_tRNS))
png_set_expand(png_ptr);
if (bit_depth == 16)
png_set_strip_16(png_ptr);
if (color_type == PNG_COLOR_TYPE_GRAY ||
color_type == PNG_COLOR_TYPE_GRAY_ALPHA)
png_set_gray_to_rgb(png_ptr);
if (png_get_gAMA(png_ptr, info_ptr, &gamma))
png_set_gamma(png_ptr, 2.2, gamma);
// all transformations have been registered; now update info_ptr data,
// get rowbytes and channels, and allocate image memory
png_read_update_info(png_ptr, info_ptr);
image_rowbytes = png_get_rowbytes(png_ptr, info_ptr);
image_channels = (int)png_get_channels(png_ptr, info_ptr);
if ((image_data = (unsigned char*)malloc(image_rowbytes*height)) == NULL)
{
png_destroy_read_struct(&png_ptr, &info_ptr, NULL);
return false;
}
if ((row_pointers = (png_bytepp)malloc(height*sizeof(png_bytep))) == NULL)
{
png_destroy_read_struct(&png_ptr, &info_ptr, NULL);
free(image_data);
return false;
}
// set the individual row_pointers to point at the correct offsets
for (i = 0; i < height; ++i)
row_pointers[i] = image_data + i*image_rowbytes;
// now we can go ahead and just read the whole image
png_read_image(png_ptr, row_pointers);
// and we're done! (png_read_end() can be omitted if no processing of
// post-IDAT text/time/etc. is desired)
free(row_pointers);
row_pointers = NULL;
png_read_end(png_ptr, NULL);
// done with PNG file, so clean up to minimize memory usage
png_destroy_read_struct(&png_ptr, &info_ptr, NULL);
if (!image_data)
return false;
// get our buffer set to hold data
m_pData = (unsigned char*)malloc(width*height*image_channels);
if (m_pData == NULL)
{
free (image_data);
return false;
}
m_nWidth = width;
m_nHeight = height;
if (image_channels == 3)
m_bAlpha = false;
else
m_bAlpha = true;
for (row = 0; row < height; row++)
{
src = image_data + row*image_rowbytes;
dest = m_pData + row*image_channels*width;
if (image_channels == 3)
{
for (i = width; i > 0; i--)
{
r = *src++;
g = *src++;
b = *src++;
*dest++ = r;
*dest++ = g;
*dest++ = b;
}
}
else // if (image_channels == 4)
{
for (i = width; i > 0; i--)
{
r = *src++;
g = *src++;
b = *src++;
a = *src++;
if (a == 255)
{
*dest++ = r;
*dest++ = g;
*dest++ = b;
}
else if (a == 0)
{
*dest++ = red;
*dest++ = green;
*dest++ = blue;
}
else
{
// this macro (copied from png.h) composites the
// foreground and background values and puts the
// result into the first argument; there are no
// side effects with the first argument
alpha_composite(*dest++, r, a, red);
alpha_composite(*dest++, g, a, green);
alpha_composite(*dest++, b, a, blue);
}
*dest++ = a;
}
}
}
free(image_data);
return true;
}
// =============================================================================
static void user_write_fn(png_structp png_ptr, png_bytep data, png_size_t length)
{
png_uint_32 check;
check = ((lcFile*)png_get_io_ptr(png_ptr))->WriteBuffer(data, length);
if (check != length)
{
png_error(png_ptr, "Write Error");
}
}
static void user_flush_fn(png_structp png_ptr)
{
((lcFile*)png_get_io_ptr(png_ptr))->Flush();
}
bool Image::SavePNG(lcFile& file, bool transparent, bool interlaced, unsigned char* background) const
{
png_structp png_ptr;
png_infop info_ptr;
png_bytepp row_pointers = NULL;
png_color_8 sig_bit;
png_color_16 bg;
int i;
png_ptr = png_create_write_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL);
if (!png_ptr)
return false;
info_ptr = png_create_info_struct(png_ptr);
if (!info_ptr)
{
png_destroy_write_struct(&png_ptr, NULL);
return false;
}
if (setjmp(png_jmpbuf(png_ptr)))
{
png_destroy_write_struct(&png_ptr, (png_infopp)NULL);
return false;
}
// png_init_io(png_ptr, fp);
png_set_write_fn(png_ptr, &file, user_write_fn, user_flush_fn);
png_set_IHDR(png_ptr, info_ptr, m_nWidth, m_nHeight, 8,
transparent ? PNG_COLOR_TYPE_RGB_ALPHA : PNG_COLOR_TYPE_RGB,
interlaced ? PNG_INTERLACE_ADAM7 : PNG_INTERLACE_NONE,
PNG_COMPRESSION_TYPE_DEFAULT, PNG_FILTER_TYPE_DEFAULT);
bg.red = background[0];
bg.green = background[1];
bg.blue = background[2];
png_set_bKGD(png_ptr, info_ptr, &bg);
png_write_info(png_ptr, info_ptr);
// Set the true bit depth of the image data
sig_bit.red = 8;
sig_bit.green = 8;
sig_bit.blue = 8;
sig_bit.alpha = 8;
png_set_sBIT(png_ptr, info_ptr, &sig_bit);
if ((row_pointers = (png_bytepp)malloc(m_nHeight*sizeof(png_bytep))) == NULL)
{
png_destroy_write_struct(&png_ptr, (png_infopp)NULL);
return false;
}
// set the individual row_pointers to point at the correct offsets
if (transparent)
{
unsigned char *buf, *src, *dst, alpha;
dst = buf = (unsigned char*)malloc(m_nWidth*m_nHeight*4);
src = m_pData;
for (i = 0; i < m_nWidth*m_nHeight; i++)
{
if ((src[0] == background[0]) &&
(src[1] == background[1]) &&
(src[2] == background[2]))
alpha = 0;
else
alpha = 255;
*dst++ = *src++;
*dst++ = *src++;
*dst++ = *src++;
*dst++ = alpha;
}
for (i = 0; i < m_nHeight; i++)
row_pointers[i] = buf + i*m_nWidth*4;
png_write_image(png_ptr, row_pointers);
free(buf);
}
else
{
for (i = 0; i < m_nHeight; i++)
row_pointers[i] = m_pData + i*m_nWidth*3;
png_write_image(png_ptr, row_pointers);
}
free(row_pointers);
png_write_end(png_ptr, info_ptr);
png_destroy_write_struct(&png_ptr, &info_ptr);
return true;
}
#endif // LC_HAVE_PNGLIB

View file

@ -1,75 +1,58 @@
// Image I/O routines
//
#include "lc_global.h"
#include "opengl.h"
#ifdef LC_WINDOWS
#include <windows.h>
#include <windowsx.h>
//#include <mmsystem.h>
#include <vfw.h>
#endif
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <math.h>
#include "image.h"
#include "lc_file.h"
// =============================================================================
// Image functions
#include "opengl.h"
Image::Image ()
{
m_nWidth = 0;
m_nHeight = 0;
m_bAlpha = false;
m_pData = NULL;
mData = NULL;
mWidth = 0;
mHeight = 0;
mAlpha = false;
}
Image::~Image ()
{
free (m_pData);
FreeData();
}
void Image::FreeData ()
{
m_nWidth = 0;
m_nHeight = 0;
m_bAlpha = false;
free (m_pData);
m_pData = NULL;
free(mData);
mData = NULL;
mWidth = 0;
mHeight = 0;
mAlpha = false;
}
void Image::Allocate (int width, int height, bool alpha)
void Image::Allocate(int Width, int Height, bool Alpha)
{
FreeData ();
m_nWidth = width;
m_nHeight = height;
m_bAlpha = alpha;
mWidth = Width;
mHeight = Height;
mAlpha = Alpha;
if (m_bAlpha)
m_pData = (unsigned char*)malloc (width * height * 4);
if (mAlpha)
mData = (unsigned char*)malloc(mWidth * mHeight * 4);
else
m_pData = (unsigned char*)malloc (width * height * 3);
mData = (unsigned char*)malloc(mWidth * mHeight * 3);
}
void Image::ResizePow2 ()
{
int i, shifted_x, shifted_y;
shifted_x = m_nWidth;
shifted_x = mWidth;
for (i = 0; ((i < 16) && (shifted_x != 0)); i++)
shifted_x = shifted_x >> 1;
shifted_x = (i != 0) ? 1 << (i-1) : 1;
shifted_y = m_nHeight;
shifted_y = mHeight;
for (i = 0; ((i < 16) && (shifted_y != 0)); i++)
shifted_y = shifted_y >> 1;
shifted_y = (i != 0) ? 1 << (i-1) : 1;
if ((shifted_x != m_nWidth) || (shifted_y != m_nHeight))
if ((shifted_x != mWidth) || (shifted_y != mHeight))
Resize (shifted_x, shifted_y);
}
@ -79,434 +62,45 @@ void Image::Resize (int width, int height)
float accumx, accumy;
unsigned char* bits;
if (m_bAlpha)
if (mAlpha)
components = 4;
else
components = 3;
bits = (unsigned char*)malloc (width * height * components);
for (j = 0; j < m_nHeight; j++)
for (j = 0; j < mHeight; j++)
{
accumy = (float)height*j/(float)m_nHeight;
accumy = (float)height*j/(float)mHeight;
sty = (int)floor(accumy);
for (i = 0; i < m_nWidth; i++)
for (i = 0; i < mWidth; i++)
{
accumx = (float)width*i/(float)m_nWidth;
accumx = (float)width*i/(float)mWidth;
stx = (int)floor(accumx);
for (k = 0; k < components; k++)
bits[(stx+sty*width)*components+k] = m_pData[(i+j*m_nWidth)*components+k];
bits[(stx+sty*width)*components+k] = mData[(i+j*mWidth)*components+k];
}
}
free (m_pData);
m_pData = bits;
m_nWidth = width;
m_nHeight = height;
free (mData);
mData = bits;
mWidth = width;
mHeight = height;
}
void Image::FromOpenGL (int width, int height)
void Image::FromOpenGL(int Width, int Height)
{
unsigned char *buf;
buf = (unsigned char*)malloc (width*height*3);
Allocate(Width, Height, true);
FreeData ();
m_pData = (unsigned char*)malloc (width*height*3);
m_nWidth = width;
m_nHeight = height;
m_bAlpha = false;
lcuint8* Buffer = (lcuint8*)malloc(Width * Height * 4);
glPixelStorei (GL_PACK_ALIGNMENT, 1);
glReadPixels (0, 0, width, height, GL_RGB, GL_UNSIGNED_BYTE, buf);
glReadPixels(0, 0, Width, Height, GL_RGBA, GL_UNSIGNED_BYTE, Buffer);
for (int row = 0; row < height; row++)
memcpy (m_pData + (row*width*3), buf + ((height-row-1)*width*3), width*3);
for (int Row = 0; Row < Height; Row++)
memcpy(mData + (Row * Width * 4), Buffer + ((Height - Row - 1) * Width * 4), Width * 4);
free (buf);
free(Buffer);
}
bool Image::FileLoad(lcFile& file)
{
unsigned char buf[8];
// Read a few bytes
if (file.ReadBuffer(buf, 8) != 8)
return false;
file.Seek (-8, SEEK_CUR);
// Check for the BMP header
if ((buf[0] == 'B') && (buf[1] == 'M'))
{
if (!LoadBMP (file))
return false;
return true;
}
#ifdef LC_HAVE_JPEGLIB
if ((buf[0] == 0xFF) && (buf[1] == 0xD8))
{
if (!LoadJPG (file))
return false;
return true;
}
#endif
#ifdef LC_HAVE_PNGLIB
const unsigned char png_signature[8] = { 137, 80, 78, 71, 13, 10, 26, 10 };
// Check for the PNG header
if (memcmp (buf, png_signature, 8) == 0)
{
if (!LoadPNG (file))
return false;
return true;
}
#endif
// Check for the GIF header
if ((buf[0] == 'G') && (buf[1] == 'I') && (buf[2] == 'F') &&
(buf[3] == '8') && ((buf[4] == '7') || (buf[4] == '9')) &&
(buf[5] == 'a'))
{
if (!LoadGIF (file))
return false;
return true;
}
// MessageBox (NULL, "Unknown File Format", "Error", MB_ICONSTOP);
return false;
}
bool Image::FileLoad(const char* filename)
{
lcDiskFile file;
if (!file.Open (filename, "rb"))
return false;
return FileLoad (file);
}
bool Image::FileSave(lcFile& file, LC_IMAGE_OPTS* opts) const
{
switch (opts->format)
{
#ifdef LC_HAVE_JPEGLIB
case LC_IMAGE_JPG:
return SaveJPG (file, opts->quality, opts->interlaced);
#endif
case LC_IMAGE_GIF:
return SaveGIF (file, opts->transparent, opts->interlaced, opts->background);
case LC_IMAGE_BMP:
return SaveBMP (file, opts->truecolor == false);
#ifdef LC_HAVE_PNGLIB
case LC_IMAGE_PNG:
return SavePNG (file, opts->transparent, opts->interlaced, opts->background);
#endif
default:
break;
}
// MessageBox (NULL, "Could not save file", "Error", MB_ICONSTOP);
return false;
}
bool Image::FileSave(const char* filename, LC_IMAGE_OPTS* opts) const
{
char name[LC_MAXPATH], ext[5], *p;
lcDiskFile file;
bool needext = false;
strcpy (name, filename);
p = name + strlen (name) - 1;
while ((p > name) && (*p != '/') && (*p != '\\') && (*p != '.'))
p--;
if (*p != '.')
needext = true;
else
{
if (strlen (p) > 5)
needext = true;
else
{
strcpy (ext, p+1);
strlwr (ext);
if (strcmp (ext, "bmp") == 0)
opts->format = LC_IMAGE_BMP;
else if (strcmp (ext, "gif") == 0)
opts->format = LC_IMAGE_GIF;
#ifdef LC_HAVE_JPEGLIB
else if (strcmp (ext, "jpg") == 0)
opts->format = LC_IMAGE_JPG;
else if (strcmp (ext, "jpeg") == 0)
opts->format = LC_IMAGE_JPG;
#endif
#ifdef LC_HAVE_PNGLIB
else if (strcmp (ext, "png") == 0)
opts->format = LC_IMAGE_PNG;
#endif
else
needext = true;
}
}
if (needext)
{
// no extension, add from the options
switch (opts->format)
{
case LC_IMAGE_BMP:
strcat (name, ".bmp");
break;
case LC_IMAGE_GIF:
strcat (name, ".gif");
break;
#ifdef LC_HAVE_JPEGLIB
case LC_IMAGE_JPG:
strcat (name, ".jpg");
break;
#endif
#ifdef LC_HAVE_PNGLIB
case LC_IMAGE_PNG:
strcat (name, ".png");
break;
#endif
default:
return false;
}
}
if (!file.Open(name, "wb"))
return false;
return FileSave(file, opts);
}
// =============================================================================
// Global functions
#ifdef LC_WINDOWS
#include "system.h"
#define AVIIF_KEYFRAME 0x00000010L // this frame is a key frame.
#define LPLPBI LPBITMAPINFOHEADER *
static HANDLE MakeDib (HBITMAP hbitmap, Image& image)
{
HANDLE hdib ;
HDC hdc ;
BITMAP bitmap ;
UINT wLineLen ;
DWORD dwSize ;
DWORD wColSize ;
LPBITMAPINFOHEADER lpbi ;
LPBYTE lpBits ;
UINT bits = 24;
int i, j;
GetObject(hbitmap,sizeof(BITMAP),&bitmap) ;
// DWORD align the width of the DIB
// Figure out the size of the colour table
// Calculate the size of the DIB
wLineLen = (bitmap.bmWidth*bits+31)/32 * 4;
wColSize = sizeof(RGBQUAD)*((bits <= 8) ? 1<<bits : 0);
dwSize = sizeof(BITMAPINFOHEADER) + wColSize +
(DWORD)(UINT)wLineLen*(DWORD)(UINT)bitmap.bmHeight;
// Allocate room for a DIB and set the LPBI fields
hdib = GlobalAlloc(GHND,dwSize);
if (!hdib)
return hdib ;
lpbi = (LPBITMAPINFOHEADER)GlobalLock(hdib) ;
lpbi->biSize = sizeof(BITMAPINFOHEADER) ;
lpbi->biWidth = bitmap.bmWidth ;
lpbi->biHeight = bitmap.bmHeight ;
lpbi->biPlanes = 1 ;
lpbi->biBitCount = (WORD) bits ;
lpbi->biCompression = BI_RGB ;
lpbi->biSizeImage = dwSize - sizeof(BITMAPINFOHEADER) - wColSize ;
lpbi->biXPelsPerMeter = 0 ;
lpbi->biYPelsPerMeter = 0 ;
lpbi->biClrUsed = (bits <= 8) ? 1<<bits : 0;
lpbi->biClrImportant = 0 ;
// Get the bits from the bitmap and stuff them after the LPBI
lpBits = (LPBYTE)(lpbi+1)+wColSize ;
hdc = CreateCompatibleDC(NULL) ;
GetDIBits(hdc,hbitmap,0,bitmap.bmHeight,lpBits,(LPBITMAPINFO)lpbi, DIB_RGB_COLORS);
for (i = 0; i < lpbi->biHeight; i++)
{
unsigned char *src = image.GetData() + i * image.Width() * 3;
unsigned char *dst = lpBits + (lpbi->biHeight - i - 1) * wLineLen;
for (j = 0; j < lpbi->biWidth; j++)
{
dst[0] = src[2];
dst[1] = src[1];
dst[2] = src[0];
src += 3;
dst += 3;
}
}
// Fix this if GetDIBits messed it up....
lpbi->biClrUsed = (bits <= 8) ? 1<<bits : 0;
DeleteDC(hdc) ;
GlobalUnlock(hdib);
return hdib ;
}
// Walk through our array of LPBI's and free them
static void FreeFrames(LPLPBI alpbi, int frames)
{
int w;
if (!alpbi[0])
return;
// Don't free a frame if it's a duplicate of the previous one
for (w=0; w < frames; w++)
if (alpbi[w] && alpbi[w] != alpbi[w-1])
GlobalFreePtr(alpbi[w]);
for (w=0; w < frames; w++)
alpbi[w] = NULL;
}
// Fill an array of LPBI's with the frames for this movie
static void MakeFrames (LPLPBI alpbi, Image *images, int frames)
{
HBITMAP hbitmap, hbitmapOld;
HDC hdc, hdcMem;
int i;
RECT rc;
hdc = GetDC (NULL);
hdcMem = CreateCompatibleDC (NULL);
hbitmap = CreateCompatibleBitmap (hdc, images[0].Width (), images[0].Height ());
// Now walk through and make all the frames
for ( i=0; i < frames; i++ )
{
hbitmapOld = SelectBitmap(hdcMem, hbitmap);
// Fill the whole frame with white
SetRect(&rc,0,0,images[0].Width (), images[0].Height ());
FillRect(hdcMem,&rc,GetStockBrush(WHITE_BRUSH));
SelectBitmap(hdcMem, hbitmapOld);
// Make this into a DIB and stuff it into the array
alpbi[i] = (LPBITMAPINFOHEADER)GlobalLock(MakeDib(hbitmap, images[i]));
// For an error, just duplicate the last frame if we can
if (alpbi[i] == NULL && i )
alpbi[i] = alpbi[i-1] ;
}
// Select all the old objects back and delete resources
DeleteBitmap(hbitmap) ;
DeleteObject(hdcMem) ;
ReleaseDC(NULL,hdc) ;
}
void SaveVideo(char* filename, Image *images, int count, float fps)
{
AVISTREAMINFO strhdr;
PAVIFILE pfile = NULL;
PAVISTREAM ps = NULL, psCompressed = NULL;
AVICOMPRESSOPTIONS opts;
AVICOMPRESSOPTIONS FAR * aopts[1] = { &opts };
LPBITMAPINFOHEADER *plpbi;
_fmemset(&opts, 0, sizeof(opts));
// first let's make sure we are running on 1.1
WORD wVer = HIWORD(VideoForWindowsVersion());
if (wVer < 0x010a)
{
SystemDoMessageBox("Video for Windows 1.1 or later required", MB_OK|MB_ICONSTOP);
return;
}
AVIFileInit();
plpbi = (LPBITMAPINFOHEADER*) malloc (count*sizeof (LPBITMAPINFOHEADER));
MakeFrames (plpbi, images, count);
if (AVIFileOpen(&pfile, filename, OF_WRITE | OF_CREATE, NULL) == AVIERR_OK)
{
// Fill in the header for the video stream.
_fmemset(&strhdr, 0, sizeof(strhdr));
strhdr.fccType = streamtypeVIDEO;
strhdr.fccHandler = 0;
strhdr.dwScale = 1;
/////////////// set FPS
strhdr.dwRate = 15; // 15 fps
strhdr.dwSuggestedBufferSize = plpbi[0]->biSizeImage;
SetRect(&strhdr.rcFrame, 0, 0, (int) plpbi[0]->biWidth, (int) plpbi[0]->biHeight);
// And create the stream.
if (AVIFileCreateStream(pfile, &ps, &strhdr) == AVIERR_OK)
if (AVISaveOptions(NULL, 0, 1, &ps, (LPAVICOMPRESSOPTIONS FAR *) &aopts))
// if (AVISaveOptions(AfxGetMainWnd()->m_hWnd, 0, 1, &ps, (LPAVICOMPRESSOPTIONS FAR *) &aopts))
if (AVIMakeCompressedStream(&psCompressed, ps, &opts, NULL) == AVIERR_OK)
if (AVIStreamSetFormat(psCompressed, 0, plpbi[0], plpbi[0]->biSize + plpbi[0]->biClrUsed * sizeof(RGBQUAD)) == AVIERR_OK)
{
float fPause = (float)Sys_ProfileLoadInt("Default", "AVI Pause", 100)/100;
int time = (int)(fPause * 15);
///////////// set FPS
time = 1;
for (int i = 0; i < count; i++)
{
if (AVIStreamWrite(psCompressed, i * time, 1,
(LPBYTE) plpbi[i] + plpbi[i]->biSize + plpbi[i]->biClrUsed * sizeof(RGBQUAD),
plpbi[i]->biSizeImage, i%5 ? 0 : AVIIF_KEYFRAME, NULL, NULL) != AVIERR_OK)
break;
}
}
}
FreeFrames (plpbi, count);
// Now close the file
if (ps) AVIStreamClose(ps);
if (psCompressed) AVIStreamClose(psCompressed);
if (pfile) AVIFileClose(pfile);
AVIFileExit();
}
#else
void SaveVideo(char* filename, Image *images, int count, float fps)
{
// SystemDoMessageBox("Format not supported under this platform.", LC_MB_OK|LC_MB_ERROR);
}
#endif

View file

@ -1,7 +1,18 @@
#ifndef _IMAGE_H_
#define _IMAGE_H_
#include "typedefs.h"
// Image Options
//#define LC_IMAGE_PROGRESSIVE 0x1000
#define LC_IMAGE_TRANSPARENT 0x2000
//#define LC_IMAGE_HIGHCOLOR 0x4000
#define LC_IMAGE_MASK 0x7000
enum LC_IMAGE_FORMAT
{
LC_IMAGE_BMP,
LC_IMAGE_JPG,
LC_IMAGE_PNG
};
class Image
{
@ -9,44 +20,21 @@ public:
Image();
virtual ~Image();
bool FileSave(lcFile& file, LC_IMAGE_OPTS* opts) const;
bool FileSave(const char* filename, LC_IMAGE_OPTS* opts) const;
bool FileLoad(lcFile& file);
bool FileLoad(const char* filename);
bool FileSave(lcMemFile& File, LC_IMAGE_FORMAT Format, bool Transparent) const;
bool FileSave(const char* FileName, LC_IMAGE_FORMAT Format, bool Transparent) const;
bool FileLoad(lcMemFile& File);
bool FileLoad(const char* FileName);
void Resize(int width, int height);
void Resize(int Width, int Height);
void ResizePow2();
void FromOpenGL(int width, int height);
void Allocate(int width, int height, bool alpha);
int Width() const
{ return m_nWidth; }
int Height() const
{ return m_nHeight; }
int Alpha() const
{ return m_bAlpha; }
unsigned char* GetData() const
{ return m_pData; }
protected:
void FromOpenGL(int Width, int Height);
void Allocate(int Width, int Height, bool Alpha);
void FreeData();
bool LoadJPG(lcFile& file);
bool LoadBMP(lcFile& file);
bool LoadPNG(lcFile& file);
bool LoadGIF(lcFile& file);
bool SaveJPG(lcFile& file, int quality, bool progressive) const;
bool SaveBMP(lcFile& file, bool quantize) const;
bool SavePNG(lcFile& file, bool transparent, bool interlaced, unsigned char* background) const;
bool SaveGIF(lcFile& file, bool transparent, bool interlaced, unsigned char* background) const;
int m_nWidth;
int m_nHeight;
bool m_bAlpha;
unsigned char* m_pData;
int mWidth;
int mHeight;
bool mAlpha;
unsigned char* mData;
};
void SaveVideo(char* filename, Image *images, int count, float fps);
#endif // _IMAGE_H_

View file

@ -1,432 +0,0 @@
//
// Code to handle user-defined keyboard shortcuts.
//
#include "lc_global.h"
#include <stdio.h>
#include "system.h"
#include "keyboard.h"
#include "lc_file.h"
#include "str.h"
// ============================================================================
// Globals.
LC_KEYBOARD_COMMAND DefaultKeyboardShortcuts[] =
{
{ LC_FILE_NEW, "New Project", LC_KEYMOD1_CONTROL, LC_KEY_N, 0 },
{ LC_FILE_OPEN, "Open Project", LC_KEYMOD1_CONTROL, LC_KEY_O, 0 },
{ LC_FILE_MERGE, "Merge Project", 0, 0, 0 },
{ LC_FILE_SAVE, "Save Project", LC_KEYMOD1_CONTROL, LC_KEY_S, 0 },
{ LC_FILE_SAVEAS, "Save Project As", 0, 0, 0 },
{ LC_FILE_PICTURE, "Save Picture", 0, 0, 0 },
{ LC_FILE_3DS, "Export 3D Studio", 0, 0, 0 },
{ LC_FILE_HTML, "Export HTML", 0, 0, 0 },
{ LC_FILE_BRICKLINK, "Export BrickLink", 0, 0, 0 },
{ LC_FILE_POVRAY, "Export POV-Ray", 0, 0, 0 },
{ LC_FILE_WAVEFRONT, "Export Wavefront", 0, 0, 0 },
{ LC_FILE_PROPERTIES, "Project Properties", 0, 0, 0 },
// { LC_FILE_TERRAIN, "Terrain Editor", 0, 0, 0 },
{ LC_FILE_LIBRARY, "Piece Library Manager", 0, 0, 0 },
// { LC_FILE_RECENT, "Open Recent File", 0, 0, 0 },
{ LC_EDIT_UNDO, "Undo", LC_KEYMOD1_CONTROL, LC_KEY_Z, 0 },
{ LC_EDIT_REDO, "Redo", LC_KEYMOD1_CONTROL, LC_KEY_Y, 0 },
{ LC_EDIT_CUT, "Cut", LC_KEYMOD1_CONTROL, LC_KEY_X, 0 },
{ LC_EDIT_COPY, "Copy", LC_KEYMOD1_CONTROL, LC_KEY_C, 0 },
{ LC_EDIT_PASTE, "Paste", LC_KEYMOD1_CONTROL, LC_KEY_V, 0 },
{ LC_EDIT_SELECT_ALL, "Select All", LC_KEYMOD1_CONTROL, LC_KEY_A, 0 },
{ LC_EDIT_SELECT_NONE, "Select None", 0, 0, 0 },
{ LC_EDIT_SELECT_INVERT, "Select Invert", LC_KEYMOD1_CONTROL, LC_KEY_I, 0 },
{ LC_EDIT_SELECT_BYNAME, "Select By Name", 0, 0, 0 },
{ LC_PIECE_INSERT, "Piece Insert", 0, LC_KEY_INSERT, 0 },
{ LC_PIECE_DELETE, "Piece Delete", 0, LC_KEY_DELETE, 0 },
// { LC_PIECE_MINIFIG, "Minifig Wizard", 0, 0, 0 },
{ LC_PIECE_ARRAY, "Piece Array", 0, 0, 0 },
// { LC_PIECE_COPYKEYS, "", 0, 0, 0 },
{ LC_PIECE_GROUP, "Piece Group", LC_KEYMOD1_CONTROL, LC_KEY_G, 0 },
{ LC_PIECE_UNGROUP, "Piece Ungroup", LC_KEYMOD1_CONTROL, LC_KEY_U, 0 },
{ LC_PIECE_GROUP_ADD, "Group Add Piece", 0, 0, 0 },
{ LC_PIECE_GROUP_REMOVE, "Group Remove Piece", 0, 0, 0 },
{ LC_PIECE_GROUP_EDIT, "Group Edit", 0, 0, 0 },
{ LC_PIECE_HIDE_SELECTED, "Hide Selection", LC_KEYMOD1_CONTROL, LC_KEY_H, 0 },
{ LC_PIECE_HIDE_UNSELECTED, "Unhide Selection", 0, 0, 0 },
{ LC_PIECE_UNHIDE_ALL, "Unhide All", 0, 0, 0 },
{ LC_PIECE_PREVIOUS, "Piece Previous Step", 0, 0, 0 },
{ LC_PIECE_NEXT, "Piece Next Step", 0, 0, 0 },
{ LC_VIEW_PREFERENCES, "Preferences", 0, 0, 0 },
// { LC_VIEW_ZOOM, "", 0, 0, 0 },
{ LC_VIEW_ZOOMIN, "Zoom In", 0, 0, 0 },
{ LC_VIEW_ZOOMOUT, "Zoom Out", 0, 0, 0 },
{ LC_VIEW_ZOOMEXTENTS, "Zoom Extents", 0, 0, 0 },
{ LC_VIEW_STEP_NEXT, "Step Next", 0, 0, 0 },
{ LC_VIEW_STEP_PREVIOUS, "Step Previous", 0, 0, 0 },
{ LC_VIEW_STEP_FIRST, "Step First", 0, 0, 0 },
{ LC_VIEW_STEP_LAST, "Step Last", 0, 0, 0 },
// { LC_VIEW_STEP_CHOOSE, "", 0, 0, 0 },
// { LC_VIEW_STEP_SET, "", 0, 0, 0 },
// { LC_VIEW_STOP, "", 0, 0, 0 },
// { LC_VIEW_PLAY, "", 0, 0, 0 },
{ LC_VIEW_VIEWPOINT_FRONT, "Viewpoint Front", LC_KEYMOD_VIEWONLY, LC_KEY_F, 0 },
{ LC_VIEW_VIEWPOINT_BACK, "Viewpoint Back", LC_KEYMOD_VIEWONLY, LC_KEY_B, 0 },
{ LC_VIEW_VIEWPOINT_TOP, "Viewpoint Top", LC_KEYMOD_VIEWONLY, LC_KEY_T, 0 },
{ LC_VIEW_VIEWPOINT_BOTTOM, "Viewpoint Bottom", LC_KEYMOD_VIEWONLY, LC_KEY_O, 0 },
{ LC_VIEW_VIEWPOINT_LEFT, "Viewpoint Left", LC_KEYMOD_VIEWONLY, LC_KEY_L, 0 },
{ LC_VIEW_VIEWPOINT_RIGHT, "Viewpoint Right", LC_KEYMOD_VIEWONLY, LC_KEY_R, 0 },
{ LC_VIEW_VIEWPOINT_HOME, "Viewpoint Home", LC_KEYMOD_VIEWONLY, LC_KEY_M, 0 },
// { LC_VIEW_CAMERA_MENU, "", 0, 0, 0 },
// { LC_VIEW_CAMERA_RESET, "", 0, 0, 0 },
// { LC_HELP_ABOUT, "", 0, 0, 0 },
// { LC_TOOLBAR_ANIMATION, "", 0, 0, 0 },
// { LC_TOOLBAR_ADDKEYS, "", 0, 0, 0 },
// { LC_TOOLBAR_SNAPMENU, "", 0, 0, 0 },
// { LC_TOOLBAR_LOCKMENU, "", 0, 0, 0 },
// { LC_TOOLBAR_FASTRENDER, "", 0, 0, 0 },
{ LC_VIEW_STEP_INSERT, "Step Insert", 0, 0, 0 },
{ LC_VIEW_STEP_DELETE, "Step Delete", 0, 0, 0 },
{ LC_EDIT_MOVEXY_SNAP_0, "Move XY Snap 0", LC_KEYMOD_VIEWONLY, LC_KEY_0, 0 },
{ LC_EDIT_MOVEXY_SNAP_1, "Move XY Snap 1", LC_KEYMOD_VIEWONLY, LC_KEY_1, 0 },
{ LC_EDIT_MOVEXY_SNAP_2, "Move XY Snap 2", LC_KEYMOD_VIEWONLY, LC_KEY_2, 0 },
{ LC_EDIT_MOVEXY_SNAP_3, "Move XY Snap 3", LC_KEYMOD_VIEWONLY, LC_KEY_3, 0 },
{ LC_EDIT_MOVEXY_SNAP_4, "Move XY Snap 4", LC_KEYMOD_VIEWONLY, LC_KEY_4, 0 },
{ LC_EDIT_MOVEXY_SNAP_5, "Move XY Snap 5", LC_KEYMOD_VIEWONLY, LC_KEY_5, 0 },
{ LC_EDIT_MOVEXY_SNAP_6, "Move XY Snap 6", LC_KEYMOD_VIEWONLY, LC_KEY_6, 0 },
{ LC_EDIT_MOVEXY_SNAP_7, "Move XY Snap 7", LC_KEYMOD_VIEWONLY, LC_KEY_7, 0 },
{ LC_EDIT_MOVEXY_SNAP_8, "Move XY Snap 8", LC_KEYMOD_VIEWONLY, LC_KEY_8, 0 },
{ LC_EDIT_MOVEXY_SNAP_9, "Move XY Snap 9", LC_KEYMOD_VIEWONLY, LC_KEY_9, 0 },
{ LC_EDIT_MOVEZ_SNAP_0, "Move Z Snap 0", LC_KEYMOD_VIEWONLY|LC_KEYMOD1_SHIFT|LC_KEYMOD1_CONTROL, LC_KEY_0, 0 },
{ LC_EDIT_MOVEZ_SNAP_1, "Move Z Snap 1", LC_KEYMOD_VIEWONLY|LC_KEYMOD1_SHIFT|LC_KEYMOD1_CONTROL, LC_KEY_1, 0 },
{ LC_EDIT_MOVEZ_SNAP_2, "Move Z Snap 2", LC_KEYMOD_VIEWONLY|LC_KEYMOD1_SHIFT|LC_KEYMOD1_CONTROL, LC_KEY_2, 0 },
{ LC_EDIT_MOVEZ_SNAP_3, "Move Z Snap 3", LC_KEYMOD_VIEWONLY|LC_KEYMOD1_SHIFT|LC_KEYMOD1_CONTROL, LC_KEY_3, 0 },
{ LC_EDIT_MOVEZ_SNAP_4, "Move Z Snap 4", LC_KEYMOD_VIEWONLY|LC_KEYMOD1_SHIFT|LC_KEYMOD1_CONTROL, LC_KEY_4, 0 },
{ LC_EDIT_MOVEZ_SNAP_5, "Move Z Snap 5", LC_KEYMOD_VIEWONLY|LC_KEYMOD1_SHIFT|LC_KEYMOD1_CONTROL, LC_KEY_5, 0 },
{ LC_EDIT_MOVEZ_SNAP_6, "Move Z Snap 6", LC_KEYMOD_VIEWONLY|LC_KEYMOD1_SHIFT|LC_KEYMOD1_CONTROL, LC_KEY_6, 0 },
{ LC_EDIT_MOVEZ_SNAP_7, "Move Z Snap 7", LC_KEYMOD_VIEWONLY|LC_KEYMOD1_SHIFT|LC_KEYMOD1_CONTROL, LC_KEY_7, 0 },
{ LC_EDIT_MOVEZ_SNAP_8, "Move Z Snap 8", LC_KEYMOD_VIEWONLY|LC_KEYMOD1_SHIFT|LC_KEYMOD1_CONTROL, LC_KEY_8, 0 },
{ LC_EDIT_MOVEZ_SNAP_9, "Move Z Snap 9", LC_KEYMOD_VIEWONLY|LC_KEYMOD1_SHIFT|LC_KEYMOD1_CONTROL, LC_KEY_9, 0 },
{ LC_EDIT_ANGLE_SNAP_0, "Angle Snap 0", LC_KEYMOD_VIEWONLY|LC_KEYMOD1_SHIFT, LC_KEY_0, 0 },
{ LC_EDIT_ANGLE_SNAP_1, "Angle Snap 1", LC_KEYMOD_VIEWONLY|LC_KEYMOD1_SHIFT, LC_KEY_1, 0 },
{ LC_EDIT_ANGLE_SNAP_2, "Angle Snap 5", LC_KEYMOD_VIEWONLY|LC_KEYMOD1_SHIFT, LC_KEY_2, 0 },
{ LC_EDIT_ANGLE_SNAP_3, "Angle Snap 10", LC_KEYMOD_VIEWONLY|LC_KEYMOD1_SHIFT, LC_KEY_3, 0 },
{ LC_EDIT_ANGLE_SNAP_4, "Angle Snap 15", LC_KEYMOD_VIEWONLY|LC_KEYMOD1_SHIFT, LC_KEY_4, 0 },
{ LC_EDIT_ANGLE_SNAP_5, "Angle Snap 30", LC_KEYMOD_VIEWONLY|LC_KEYMOD1_SHIFT, LC_KEY_5, 0 },
{ LC_EDIT_ANGLE_SNAP_6, "Angle Snap 45", LC_KEYMOD_VIEWONLY|LC_KEYMOD1_SHIFT, LC_KEY_6, 0 },
{ LC_EDIT_ANGLE_SNAP_7, "Angle Snap 60", LC_KEYMOD_VIEWONLY|LC_KEYMOD1_SHIFT, LC_KEY_7, 0 },
{ LC_EDIT_ANGLE_SNAP_8, "Angle Snap 90", LC_KEYMOD_VIEWONLY|LC_KEYMOD1_SHIFT, LC_KEY_8, 0 },
{ LC_EDIT_ANGLE_SNAP_9, "Angle Snap 180", LC_KEYMOD_VIEWONLY|LC_KEYMOD1_SHIFT, LC_KEY_9, 0 },
{ LC_EDIT_ACTION_SELECT, "Select Mode", 0, 0, 0 },
{ LC_EDIT_ACTION_INSERT, "Insert Mode", 0, 0, 0 },
{ LC_EDIT_ACTION_LIGHT, "Light Mode", 0, 0, 0 },
{ LC_EDIT_ACTION_SPOTLIGHT, "Spotlight Mode", 0, 0, 0 },
{ LC_EDIT_ACTION_CAMERA, "Camera Mode", 0, 0, 0 },
{ LC_EDIT_ACTION_MOVE, "Move Mode", LC_KEYMOD1_SHIFT, LC_KEY_M, 0 },
{ LC_EDIT_ACTION_ROTATE, "Rotate Mode", LC_KEYMOD1_SHIFT, LC_KEY_R, 0 },
{ LC_EDIT_ACTION_ERASER, "Eraser Mode", LC_KEYMOD1_SHIFT, LC_KEY_E, 0 },
{ LC_EDIT_ACTION_PAINT, "Paint Mode", LC_KEYMOD1_SHIFT, LC_KEY_N, 0 },
{ LC_EDIT_ACTION_ZOOM, "Zoom Mode", LC_KEYMOD1_SHIFT, LC_KEY_Z, 0 },
{ LC_EDIT_ACTION_ZOOM_REGION, "Zoom Region Mode", 0, 0, 0 },
{ LC_EDIT_ACTION_PAN, "Pan Mode", LC_KEYMOD1_SHIFT, LC_KEY_P, 0 },
{ LC_EDIT_ACTION_ROTATE_VIEW, "Rotate View Mode", LC_KEYMOD1_SHIFT, LC_KEY_T, 0 },
{ LC_EDIT_ACTION_ROLL, "Roll Camera Mode", LC_KEYMOD1_SHIFT, LC_KEY_L, 0 },
};
const int KeyboardShortcutsCount = sizeof(DefaultKeyboardShortcuts)/sizeof(KeyboardShortcuts[0]);
LC_KEYBOARD_COMMAND KeyboardShortcuts[KeyboardShortcutsCount];
// ============================================================================
// Functions
bool SaveKeyboardShortcuts(const char* FileName)
{
lcDiskFile f;
if (!f.Open(FileName, "wt"))
return false;
for (int i = 0; i < KeyboardShortcutsCount; i++)
{
LC_KEYBOARD_COMMAND& Cmd = KeyboardShortcuts[i];
String str;
str = Cmd.Description;
str += "=";
if (Cmd.Key1)
{
if (Cmd.Flags & LC_KEYMOD1_SHIFT)
str += "Shift+";
if (Cmd.Flags & LC_KEYMOD1_CONTROL)
str += "Ctrl+";
str += "\"";
str += GetKeyName(Cmd.Key1);
str += "\"";
}
if (Cmd.Key2)
{
str += ",";
if (Cmd.Flags & LC_KEYMOD2_SHIFT)
str += "Shift+";
if (Cmd.Flags & LC_KEYMOD2_CONTROL)
str += "Ctrl+";
str += "\"";
str += GetKeyName(Cmd.Key2);
str += "\"";
}
str += "\n";
f.WriteBuffer((const char*)str, str.GetLength());
}
return true;
}
bool LoadKeyboardShortcuts(const char* FileName)
{
lcDiskFile f;
int i;
if (!f.Open(FileName, "rt"))
return false;
// Remove all existing shortcuts
for (i = 0; i < KeyboardShortcutsCount; i++)
{
LC_KEYBOARD_COMMAND& Cmd = KeyboardShortcuts[i];
Cmd.Key1 = 0;
Cmd.Key2 = 0;
Cmd.Flags = DefaultKeyboardShortcuts[i].Flags & ~LC_KEYMOD_MASK;
}
char Line[1024];
while (f.ReadLine(Line, 1024))
{
char* ptr = strchr(Line, '=');
if (ptr == NULL)
continue;
*ptr = 0;
ptr++;
for (i = 0; i < KeyboardShortcutsCount; i++)
{
LC_KEYBOARD_COMMAND& Cmd = KeyboardShortcuts[i];
if (strcmp(Line, Cmd.Description))
continue;
if (!strncmp(ptr, "Shift+", 6))
{
Cmd.Flags |= LC_KEYMOD1_SHIFT;
ptr += 6;
}
if (!strncmp(ptr, "Ctrl+", 5))
{
Cmd.Flags |= LC_KEYMOD1_CONTROL;
ptr += 5;
}
ptr++;
char* ptr2 = strchr(ptr, '\"');
if (ptr2 == NULL)
{
Cmd.Flags &= ~(LC_KEYMOD1_SHIFT | LC_KEYMOD1_CONTROL);
break;
}
*ptr2 = 0;
Cmd.Key1 = GetKeyFromName(ptr);
ptr = ptr2 + 1;
if (*ptr != ',')
break;
ptr++;
if (!strncmp(ptr, "Shift+", 6))
{
Cmd.Flags |= LC_KEYMOD2_SHIFT;
ptr += 6;
}
if (!strncmp(ptr, "Ctrl+", 5))
{
Cmd.Flags |= LC_KEYMOD2_CONTROL;
ptr += 5;
}
ptr++;
ptr2 = strchr(ptr, '\"');
if (ptr2 == NULL)
{
Cmd.Flags &= ~(LC_KEYMOD2_SHIFT | LC_KEYMOD2_CONTROL);
break;
}
*ptr2 = 0;
Cmd.Key2 = GetKeyFromName(ptr);
break;
}
}
return true;
}
void ResetKeyboardShortcuts()
{
memcpy(KeyboardShortcuts, DefaultKeyboardShortcuts, sizeof(KeyboardShortcuts));
}
void InitKeyboardShortcuts()
{
const char* FileName = Sys_ProfileLoadString("Settings", "Keyboard", "");
ResetKeyboardShortcuts();
LoadKeyboardShortcuts(FileName);
}
struct LC_KEYNAME_ENTRY
{
int Key;
const char* Name;
};
static LC_KEYNAME_ENTRY KeyNames[] =
{
{ LC_KEY_BACK, "Backspace" },
{ LC_KEY_TAB, "Tab" },
{ LC_KEY_RETURN, "Return" },
{ LC_KEY_PAUSE, "Pause" },
{ LC_KEY_CAPITAL, "Caps" },
{ LC_KEY_ESCAPE, "Escape" },
{ LC_KEY_SPACE, "Space" },
{ LC_KEY_PRIOR, "Page Up" },
{ LC_KEY_NEXT, "Page Down" },
{ LC_KEY_END, "End" },
{ LC_KEY_HOME, "Home" },
{ LC_KEY_LEFT, "Left" },
{ LC_KEY_UP, "Up" },
{ LC_KEY_RIGHT, "Right" },
{ LC_KEY_DOWN, "Down" },
{ LC_KEY_SELECT, "Select" },
{ LC_KEY_PRINT, "Print" },
{ LC_KEY_INSERT, "Insert" },
{ LC_KEY_DELETE, "Delete" },
{ LC_KEY_0, "0" },
{ LC_KEY_1, "1" },
{ LC_KEY_2, "2" },
{ LC_KEY_3, "3" },
{ LC_KEY_4, "4" },
{ LC_KEY_5, "5" },
{ LC_KEY_6, "6" },
{ LC_KEY_7, "7" },
{ LC_KEY_8, "8" },
{ LC_KEY_9, "9" },
{ LC_KEY_A, "A" },
{ LC_KEY_B, "B" },
{ LC_KEY_C, "C" },
{ LC_KEY_D, "D" },
{ LC_KEY_E, "E" },
{ LC_KEY_F, "F" },
{ LC_KEY_G, "G" },
{ LC_KEY_H, "H" },
{ LC_KEY_I, "I" },
{ LC_KEY_J, "J" },
{ LC_KEY_K, "K" },
{ LC_KEY_L, "L" },
{ LC_KEY_M, "M" },
{ LC_KEY_N, "N" },
{ LC_KEY_O, "O" },
{ LC_KEY_P, "P" },
{ LC_KEY_Q, "Q" },
{ LC_KEY_R, "R" },
{ LC_KEY_S, "S" },
{ LC_KEY_T, "T" },
{ LC_KEY_U, "U" },
{ LC_KEY_V, "V" },
{ LC_KEY_W, "W" },
{ LC_KEY_X, "X" },
{ LC_KEY_Y, "Y" },
{ LC_KEY_Z, "Z" },
{ LC_KEY_NUMPAD0, "Numpad 0" },
{ LC_KEY_NUMPAD1, "Numpad 1" },
{ LC_KEY_NUMPAD2, "Numpad 2" },
{ LC_KEY_NUMPAD3, "Numpad 3" },
{ LC_KEY_NUMPAD4, "Numpad 4" },
{ LC_KEY_NUMPAD5, "Numpad 5" },
{ LC_KEY_NUMPAD6, "Numpad 6" },
{ LC_KEY_NUMPAD7, "Numpad 7" },
{ LC_KEY_NUMPAD8, "Numpad 8" },
{ LC_KEY_NUMPAD9, "Numpad 9" },
{ LC_KEY_MULTIPLY, "Numpad *" },
{ LC_KEY_ADD, "Numpad +" },
{ LC_KEY_SUBTRACT, "Numpad -" },
{ LC_KEY_DECIMAL, "Numpad ." },
{ LC_KEY_DIVIDE, "Numpad /" },
{ LC_KEY_F1, "F1" },
{ LC_KEY_F2, "F2" },
{ LC_KEY_F3, "F3" },
{ LC_KEY_F4, "F4" },
{ LC_KEY_F5, "F5" },
{ LC_KEY_F6, "F6" },
{ LC_KEY_F7, "F7" },
{ LC_KEY_F8, "F8" },
{ LC_KEY_F9, "F9" },
{ LC_KEY_F10, "F10" },
{ LC_KEY_F11, "F11" },
{ LC_KEY_F12, "F12" },
{ LC_KEY_F13, "F13" },
{ LC_KEY_F14, "F14" },
{ LC_KEY_F15, "F15" },
{ LC_KEY_F16, "F16" },
{ LC_KEY_F17, "F17" },
{ LC_KEY_F18, "F18" },
{ LC_KEY_F19, "F19" },
{ LC_KEY_F20, "F20" },
{ LC_KEY_F21, "F21" },
{ LC_KEY_F22, "F22" },
{ LC_KEY_F23, "F23" },
{ LC_KEY_F24, "F24" },
{ LC_KEY_NUMLOCK, "Num Lock" },
{ LC_KEY_SCROLL, "Scroll" }
};
// Returns a string with the name of the key.
const char* GetKeyName(char Key)
{
int Count = sizeof(KeyNames)/sizeof(KeyNames[0]);
for (int i = 0; i < Count; i++)
{
if (Key == KeyNames[i].Key)
return KeyNames[i].Name;
}
return NULL;
}
char GetKeyFromName(const char* Name)
{
int Count = sizeof(KeyNames)/sizeof(KeyNames[0]);
for (int i = 0; i < Count; i++)
{
if (!strcmp(Name, KeyNames[i].Name))
return KeyNames[i].Key;
}
return 0;
}

View file

@ -1,151 +0,0 @@
#ifndef _KEYBOARD_H_
#define _KEYBOARD_H_
#include "typedefs.h"
// ============================================================================
// Keyboard keys.
#define LC_KEY_BACK 0x08
#define LC_KEY_TAB 0x09
#define LC_KEY_RETURN 0x0D
#define LC_KEY_PAUSE 0x13
#define LC_KEY_CAPITAL 0x14
#define LC_KEY_ESCAPE 0x1B
#define LC_KEY_SPACE 0x20
#define LC_KEY_PRIOR 0x21
#define LC_KEY_NEXT 0x22
#define LC_KEY_END 0x23
#define LC_KEY_HOME 0x24
#define LC_KEY_LEFT 0x25
#define LC_KEY_UP 0x26
#define LC_KEY_RIGHT 0x27
#define LC_KEY_DOWN 0x28
#define LC_KEY_SELECT 0x29
#define LC_KEY_PRINT 0x2A
#define LC_KEY_INSERT 0x2D
#define LC_KEY_DELETE 0x2E
#define LC_KEY_0 0x30
#define LC_KEY_1 0x31
#define LC_KEY_2 0x32
#define LC_KEY_3 0x33
#define LC_KEY_4 0x34
#define LC_KEY_5 0x35
#define LC_KEY_6 0x36
#define LC_KEY_7 0x37
#define LC_KEY_8 0x38
#define LC_KEY_9 0x39
#define LC_KEY_A 0x41
#define LC_KEY_B 0x42
#define LC_KEY_C 0x43
#define LC_KEY_D 0x44
#define LC_KEY_E 0x45
#define LC_KEY_F 0x46
#define LC_KEY_G 0x47
#define LC_KEY_H 0x48
#define LC_KEY_I 0x49
#define LC_KEY_J 0x4A
#define LC_KEY_K 0x4B
#define LC_KEY_L 0x4C
#define LC_KEY_M 0x4D
#define LC_KEY_N 0x4E
#define LC_KEY_O 0x4F
#define LC_KEY_P 0x50
#define LC_KEY_Q 0x51
#define LC_KEY_R 0x52
#define LC_KEY_S 0x53
#define LC_KEY_T 0x54
#define LC_KEY_U 0x55
#define LC_KEY_V 0x56
#define LC_KEY_W 0x57
#define LC_KEY_X 0x58
#define LC_KEY_Y 0x59
#define LC_KEY_Z 0x5A
#define LC_KEY_NUMPAD0 0x60
#define LC_KEY_NUMPAD1 0x61
#define LC_KEY_NUMPAD2 0x62
#define LC_KEY_NUMPAD3 0x63
#define LC_KEY_NUMPAD4 0x64
#define LC_KEY_NUMPAD5 0x65
#define LC_KEY_NUMPAD6 0x66
#define LC_KEY_NUMPAD7 0x67
#define LC_KEY_NUMPAD8 0x68
#define LC_KEY_NUMPAD9 0x69
#define LC_KEY_MULTIPLY 0x6A
#define LC_KEY_ADD 0x6B
//#define LC_KEY_SEPARATOR 0x6C
#define LC_KEY_SUBTRACT 0x6D
#define LC_KEY_DECIMAL 0x6E
#define LC_KEY_DIVIDE 0x6F
#define LC_KEY_F1 0x70
#define LC_KEY_F2 0x71
#define LC_KEY_F3 0x72
#define LC_KEY_F4 0x73
#define LC_KEY_F5 0x74
#define LC_KEY_F6 0x75
#define LC_KEY_F7 0x76
#define LC_KEY_F8 0x77
#define LC_KEY_F9 0x78
#define LC_KEY_F10 0x79
#define LC_KEY_F11 0x7A
#define LC_KEY_F12 0x7B
#define LC_KEY_F13 0x7C
#define LC_KEY_F14 0x7D
#define LC_KEY_F15 0x7E
#define LC_KEY_F16 0x7F
#define LC_KEY_F17 0x80
#define LC_KEY_F18 0x81
#define LC_KEY_F19 0x82
#define LC_KEY_F20 0x83
#define LC_KEY_F21 0x84
#define LC_KEY_F22 0x85
#define LC_KEY_F23 0x86
#define LC_KEY_F24 0x87
#define LC_KEY_NUMLOCK 0x90
#define LC_KEY_SCROLL 0x91
// ============================================================================
// Functions.
#define LC_KEYMOD1_SHIFT 0x01
#define LC_KEYMOD1_CONTROL 0x02
#define LC_KEYMOD2_SHIFT 0x04
#define LC_KEYMOD2_CONTROL 0x08
#define LC_KEYMOD_VIEWONLY 0x10
#define LC_KEYMOD1_MASK (LC_KEYMOD1_SHIFT | LC_KEYMOD1_CONTROL)
#define LC_KEYMOD2_MASK (LC_KEYMOD2_SHIFT | LC_KEYMOD2_CONTROL)
#define LC_KEYMOD_MASK (LC_KEYMOD1_MASK | LC_KEYMOD2_MASK)
#define LC_KEYMOD_1TO2(a) ((a & ~LC_KEYMOD_MASK) | ((a & LC_KEYMOD1_MASK) << 2))
#define LC_KEYMOD_2TO1(a) ((a & ~LC_KEYMOD_MASK) | ((a & LC_KEYMOD2_MASK) >> 2))
struct LC_KEYBOARD_COMMAND
{
LC_COMMANDS ID;
const char* Description;
unsigned char Flags;
unsigned char Key1;
unsigned char Key2;
};
extern LC_KEYBOARD_COMMAND KeyboardShortcuts[];
extern const int KeyboardShortcutsCount;
const char* GetKeyName(char Key);
char GetKeyFromName(const char* Name);
void InitKeyboardShortcuts();
void ResetKeyboardShortcuts();
bool SaveKeyboardShortcuts(const char* FileName);
bool LoadKeyboardShortcuts(const char* FileName);
#endif // _KEYBOARD_H_

View file

@ -1,427 +1,385 @@
#include "lc_global.h"
#include <stdio.h>
#include "lc_application.h"
#include "lc_colors.h"
#include "lc_library.h"
#include "system.h"
#include "console.h"
#include "opengl.h"
#include "project.h"
#include "image.h"
// ----------------------------------------------------------------------------
// Global functions.
lcApplication* g_App;
lcPiecesLibrary* 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* LibraryInstallPath, const char* LibraryCachePath)
{
if (m_Library == NULL)
m_Library = new lcPiecesLibrary();
if (LibPath && LibPath[0])
{
if (m_Library->Load(LibPath, LibraryCachePath))
return true;
}
else
{
char* EnvPath = getenv("LEOCAD_LIB");
if (EnvPath && EnvPath[0])
{
if (m_Library->Load(EnvPath, LibraryCachePath))
return true;
}
else
{
const char* CustomPath = Sys_ProfileLoadString("Settings", "CustomPiecesLibrary", "");
if (CustomPath[0])
{
if (m_Library->Load(CustomPath, LibraryCachePath))
return true;
}
else if (LibraryInstallPath && LibraryInstallPath[0])
{
char LibraryPath[LC_MAXPATH];
strcpy(LibraryPath, LibraryInstallPath);
int i = strlen(LibraryPath) - 1;
if ((LibraryPath[i] != '\\') && (LibraryPath[i] != '/'))
strcat(LibraryPath, "/");
strcat(LibraryPath, "library.bin");
if (m_Library->Load(LibraryPath, LibraryCachePath))
{
m_Library->mNumOfficialPieces = m_Library->mPieces.GetSize();
return true;
}
}
}
}
return false;
}
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* LibraryInstallPath, const char* LibraryCachePath)
{
// System setup parameters.
char* LibPath = NULL;
char* GLPath = NULL;
// 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);
}
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 "\n");
printf("Copyright (c) 1996-2006, BT Software\n");
printf("Compiled "__DATE__"\n");
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");
printf(" -l, --libpath <path>: Loads the Pieces Library from path.\n");
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");
return false;
}
else
console.PrintWarning("Unknown parameter: %s\n", Param);
}
else
{
ProjectName = Param;
}
}
// Initialize other systems.
if (!GL_Initialize(GLPath))
return false;
if (!LoadPiecesLibrary(LibPath, LibraryInstallPath, LibraryCachePath))
{
if (SaveImage)
{
fprintf(stderr, "ERROR: Cannot load pieces library.");
return false;
}
m_Library->CreateBuiltinPieces();
SystemDoMessageBox("LeoCAD could not find a compatible Pieces Library so only a small number of pieces will be available.\n\n"
"Please visit http://www.leocad.org for information on how to download and install a library.", LC_MB_OK | LC_MB_ICONERROR);
}
SystemInit();
// Create a new project.
Project* project = new Project();
AddProject(project);
GL_DisableVertexBufferObject();
// 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();
}
#include "lc_global.h"
#include <stdio.h>
#include "lc_application.h"
#include "lc_colors.h"
#include "lc_library.h"
#include "lc_profile.h"
#include "system.h"
#include "console.h"
#include "opengl.h"
#include "project.h"
#include "image.h"
#include "mainwnd.h"
#include "lc_shortcuts.h"
lcApplication* g_App;
lcApplication::lcApplication()
{
mProject = NULL;
m_Library = NULL;
mClipboard = NULL;
}
lcApplication::~lcApplication()
{
delete mClipboard;
}
void lcApplication::SetClipboard(lcFile* Clipboard)
{
delete mClipboard;
mClipboard = Clipboard;
gMainWindow->UpdatePaste(mClipboard != NULL);
}
bool lcApplication::LoadPiecesLibrary(const char* LibPath, const char* LibraryInstallPath, const char* LibraryCachePath)
{
if (m_Library == NULL)
m_Library = new lcPiecesLibrary();
if (LibPath && LibPath[0])
{
if (m_Library->Load(LibPath, LibraryCachePath))
return true;
}
else
{
char* EnvPath = getenv("LEOCAD_LIB");
if (EnvPath && EnvPath[0])
{
if (m_Library->Load(EnvPath, LibraryCachePath))
return true;
}
else
{
char CustomPath[LC_MAXPATH];
strcpy(CustomPath, lcGetProfileString(LC_PROFILE_PARTS_LIBRARY));
if (CustomPath[0])
{
if (m_Library->Load(CustomPath, LibraryCachePath))
return true;
}
else if (LibraryInstallPath && LibraryInstallPath[0])
{
char LibraryPath[LC_MAXPATH];
strcpy(LibraryPath, LibraryInstallPath);
int i = strlen(LibraryPath) - 1;
if ((LibraryPath[i] != '\\') && (LibraryPath[i] != '/'))
strcat(LibraryPath, "/");
strcat(LibraryPath, "library.bin");
if (m_Library->Load(LibraryPath, LibraryCachePath))
{
m_Library->mNumOfficialPieces = m_Library->mPieces.GetSize();
return true;
}
}
}
}
return false;
}
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* LibraryInstallPath, const char* LibraryCachePath)
{
// System setup parameters.
char* LibPath = NULL;
char* GLPath = NULL;
// Image output options.
bool SaveImage = false;
bool ImageAnimation = false;
bool ImageInstructions = false;
bool ImageHighlight = false;
int ImageWidth = lcGetProfileInt(LC_PROFILE_IMAGE_WIDTH);
int ImageHeight = lcGetProfileInt(LC_PROFILE_IMAGE_HEIGHT);
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);
}
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 "\n");
printf("Compiled "__DATE__"\n");
return false;
}
else if ((strcmp(Param, "-?") == 0) || (strcmp(Param, "--help") == 0))
{
printf("Usage: leocad [options] [file]\n");
printf(" [options] can be:\n");
printf(" -l, --libpath <path>: Loads the Pieces Library from path.\n");
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");
return false;
}
else
console.PrintWarning("Unknown parameter: %s\n", Param);
}
else
{
ProjectName = Param;
}
}
if (!LoadPiecesLibrary(LibPath, LibraryInstallPath, LibraryCachePath))
{
if (SaveImage)
{
fprintf(stderr, "ERROR: Cannot load pieces library.");
return false;
}
m_Library->CreateBuiltinPieces();
gMainWindow->DoMessageBox("LeoCAD could not find a compatible Pieces Library so only a small number of pieces will be available.\n\n"
"Please visit http://www.leocad.org for information on how to download and install a library.", LC_MB_OK | LC_MB_ICONERROR);
}
// Create a new project.
mProject = new Project();
GL_DisableVertexBufferObject();
// Load project.
if (ProjectName && mProject->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")
NeedExt = false;
else if ((Ext == "jpg") || (Ext == "jpeg"))
NeedExt = false;
else if (Ext == "png")
NeedExt = false;
}
// Setup default options.
int ImageOptions = lcGetProfileInt(LC_PROFILE_IMAGE_OPTIONS);
bool ImageTransparent = (ImageOptions & LC_IMAGE_TRANSPARENT) != 0;
LC_IMAGE_FORMAT ImageFormat = (LC_IMAGE_FORMAT)(ImageOptions & ~(LC_IMAGE_MASK));
// Append file extension if needed.
if (NeedExt)
{
switch (ImageFormat)
{
case LC_IMAGE_BMP:
FileName += ".bmp";
break;
case LC_IMAGE_JPG:
FileName += ".jpg";
break;
default:
case LC_IMAGE_PNG:
FileName += ".png";
break;
}
}
if (ImageInstructions)
mProject->SetAnimation(false);
else if (ImageAnimation)
mProject->SetAnimation(true);
if (ImageEnd < ImageStart)
ImageEnd = ImageStart;
else if (ImageStart > ImageEnd)
ImageStart = ImageEnd;
if ((ImageStart == 0) && (ImageEnd == 0))
{
ImageStart = ImageEnd = mProject->GetCurrentTime();
}
else if ((ImageStart == 0) && (ImageEnd != 0))
{
ImageStart = ImageEnd;
}
else if ((ImageStart != 0) && (ImageEnd == 0))
{
ImageEnd = ImageStart;
}
if (mProject->IsAnimation())
{
if (ImageStart > mProject->GetTotalFrames())
ImageStart = mProject->GetTotalFrames();
if (ImageEnd > mProject->GetTotalFrames())
ImageEnd = mProject->GetTotalFrames();
}
else
{
if (ImageStart > 255)
ImageStart = 255;
if (ImageEnd > 255)
ImageEnd = 255;
}
Image* images = new Image[ImageEnd - ImageStart + 1];
mProject->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, ImageFormat, ImageTransparent);
}
delete []images;
return false;
}
else
{
if (SaveImage)
return false;
else
mProject->OnNewDocument();
}
lcLoadDefaultKeyboardShortcuts();
return true;
}
void lcApplication::Shutdown()
{
delete m_Library;
m_Library = NULL;
}

View file

@ -1,51 +1,47 @@
#ifndef _LC_APPLICATION_H_
#define _LC_APPLICATION_H_
#include "array.h"
class Project;
class lcPiecesLibrary;
class lcApplication
{
public:
lcApplication();
~lcApplication();
bool Initialize(int argc, char *argv[], const char* LibraryInstallPath, const char* LibraryCachePath);
void Shutdown();
// Pieces library.
bool LoadPiecesLibrary(const char* LibPath, const char* LibraryInstallPath, const char* LibraryCachePath);
lcPiecesLibrary* GetPiecesLibrary() const
{
return m_Library;
}
// Projects.
void AddProject(Project* project);
Project* GetActiveProject() const
{
return m_ActiveProject;
}
void SetActiveProject(Project* project)
{
m_ActiveProject = project;
}
protected:
void ParseIntegerArgument(int* CurArg, int argc, char* argv[], int* Value);
void ParseStringArgument(int* CurArg, int argc, char* argv[], char** Value);
Project* m_ActiveProject;
PtrArray<Project> m_Projects;
lcPiecesLibrary* m_Library;
};
extern lcApplication* g_App;
lcPiecesLibrary* lcGetPiecesLibrary();
Project* lcGetActiveProject();
#endif // _LC_APPLICATION_H_
#ifndef _LC_APPLICATION_H_
#define _LC_APPLICATION_H_
#include "array.h"
#include "str.h"
class Project;
class lcPiecesLibrary;
class lcApplication
{
public:
lcApplication();
~lcApplication();
bool Initialize(int argc, char *argv[], const char* LibraryInstallPath, const char* LibraryCachePath);
void Shutdown();
bool LoadPiecesLibrary(const char* LibPath, const char* LibraryInstallPath, const char* LibraryCachePath);
void GetFileList(const char* Path, ObjArray<String>& FileList);
void OpenURL(const char* URL);
void SetClipboard(lcFile* Clipboard);
void ExportClipboard(lcMemFile* Clipboard);
Project* mProject;
lcPiecesLibrary* m_Library;
lcFile* mClipboard;
protected:
void ParseIntegerArgument(int* CurArg, int argc, char* argv[], int* Value);
void ParseStringArgument(int* CurArg, int argc, char* argv[], char** Value);
};
extern lcApplication* g_App;
inline lcPiecesLibrary* lcGetPiecesLibrary()
{
return g_App->m_Library;
}
inline Project* lcGetActiveProject()
{
return g_App->mProject;
}
#endif // _LC_APPLICATION_H_

152
common/lc_category.cpp Normal file
View file

@ -0,0 +1,152 @@
#include "lc_global.h"
#include "lc_category.h"
#include "lc_file.h"
#include "lc_profile.h"
ObjArray<lcLibraryCategory> gCategories;
void lcResetDefaultCategories()
{
lcResetCategories(gCategories);
lcRemoveProfileKey(LC_PROFILE_CATEGORIES);
}
void lcLoadDefaultCategories(bool BuiltInLibrary)
{
lcMemFile File;
lcGetProfileBuffer(LC_PROFILE_CATEGORIES, File);
if (!File.GetLength() || !lcLoadCategories(File, gCategories))
lcResetCategories(gCategories, BuiltInLibrary);
}
void lcSaveDefaultCategories()
{
lcMemFile File;
lcSaveCategories(File, gCategories);
lcSetProfileBuffer(LC_PROFILE_CATEGORIES, File);
}
void lcResetCategories(ObjArray<lcLibraryCategory>& Categories, bool BuiltInLibrary)
{
const char DefaultCategories[] =
{
"Animal=^%Animal | ^%Bone\n"
"Antenna=^%Antenna\n"
"Arch=^%Arch\n"
"Bar=^%Bar\n"
"Baseplate=^%Baseplate | ^%Platform\n"
"Boat=^%Boat\n"
"Brick=^%Brick\n"
"Container=^%Container | ^%Box | ^Chest | ^%Storage | ^Mailbox\n"
"Door and Window=^%Door | ^%Window | ^%Glass | ^%Freestyle | ^%Gate | ^%Garage | ^%Roller\n"
"Electric=^%Electric\n"
"Hinge and Bracket=^%Hinge | ^%Bracket | ^%Turntable\n"
"Hose=^%Hose | ^%String\n"
"Minifig=^%Minifig\n"
"Miscellaneous=^%Arm | ^%Barrel | ^%Brush | ^%Claw | ^%Cockpit | ^%Conveyor | ^%Crane | ^%Cupboard | ^%Fence | ^%Jack | ^%Ladder | ^%Motor | ^%Rock | ^%Rope | ^%Sheet | ^%Sports | ^%Staircase | ^%Stretcher | ^%Tap | ^%Tipper | ^%Trailer | ^%Umbrella | ^%Winch\n"
"Other=^%Ball | ^%Belville | ^%Die | ^%Duplo | ^%Fabuland | ^%Figure | ^%Homemaker | ^%Maxifig | ^%Microfig | ^%Mursten | ^%Scala | ^%Znap\n"
"Panel=^%Panel | ^%Castle Wall | ^%Castle Turret\n"
"Plant=^%Plant\n"
"Plate=^%Plate\n"
"Round=^%Cylinder | ^%Cone | ^%Dish | ^%Dome | ^%Hemisphere | ^%Round\n"
"Sign and Flag=^%Flag | ^%Roadsign | ^%Streetlight | ^%Flagpost | ^%Lamppost | ^%Signpost\n"
"Slope=^%Slope | ^%Roof\n"
"Space=^%Space\n"
"Sticker=^%Sticker\n"
"Support=^%Support\n"
"Technic=^%Technic | ^%Rack\n"
"Tile=^%Tile\n"
"Train=^%Train | ^%Monorail | ^%Magnet\n"
"Tyre and Wheel=^%Tyre | %^Wheel | %^Wheels | ^%Castle Wagon\n"
"Vehicle=^%Bike | ^%Canvas | ^%Car | ^%Excavator | ^%Exhaust | ^%Forklift | ^%Grab Jaw | ^%Landing | ^%Motorcycle | ^%Plane | ^%Propellor | ^%Tail | ^%Tractor | ^%Vehicle | ^%Wheelbarrow\n"
"Windscreen=^%Windscreen\n"
"Wedge=^%Wedge\n"
"Wing=^%Wing\n"
};
const char BuiltInCategories[] =
{
"Brick=^%Brick\n"
"Plate=^%Plate\n"
};
lcMemFile File;
if (BuiltInLibrary)
File.WriteBuffer(BuiltInCategories, sizeof(BuiltInCategories));
else
File.WriteBuffer(DefaultCategories, sizeof(DefaultCategories));
File.Seek(0, SEEK_SET);
lcLoadCategories(File, Categories);
}
bool lcLoadCategories(const char* FileName, ObjArray<lcLibraryCategory>& Categories)
{
lcDiskFile File;
if (!File.Open(FileName, "rt"))
return false;
return lcLoadCategories(File, Categories);
}
bool lcLoadCategories(lcFile& File, ObjArray<lcLibraryCategory>& Categories)
{
Categories.RemoveAll();
char Line[1024];
while (File.ReadLine(Line, sizeof(Line)))
{
char* Key = strchr(Line, '=');
if (!Key)
continue;
*Key = 0;
Key++;
char* NewLine = strchr(Key, '\n');
if (NewLine)
*NewLine = 0;
lcLibraryCategory& Category = Categories.Add();
Category.Name = Line;
Category.Keywords = Key;
}
return true;
}
bool lcSaveCategories(const char* FileName, const ObjArray<lcLibraryCategory>& Categories)
{
lcDiskFile File;
if (!File.Open(FileName, "wt"))
return false;
return lcSaveCategories(File, Categories);
}
bool lcSaveCategories(lcFile& File, const ObjArray<lcLibraryCategory>& Categories)
{
char Line[1024];
for (int CategoryIdx = 0; CategoryIdx < Categories.GetSize(); CategoryIdx++)
{
lcLibraryCategory& Category = Categories[CategoryIdx];
sprintf(Line, "%s=%s\n", (const char*)Category.Name, (const char*)Category.Keywords);
File.WriteLine(Line);
}
return true;
}

25
common/lc_category.h Normal file
View file

@ -0,0 +1,25 @@
#ifndef _LC_CATEGORY_H_
#define _LC_CATEGORY_H_
#include "str.h"
#include "array.h"
struct lcLibraryCategory
{
String Name;
String Keywords;
};
extern ObjArray<lcLibraryCategory> gCategories;
void lcResetDefaultCategories();
void lcLoadDefaultCategories(bool BuiltInLibrary = false);
void lcSaveDefaultCategories();
void lcResetCategories(ObjArray<lcLibraryCategory>& Categories, bool BuiltInLibrary = false);
bool lcLoadCategories(const char* FileName, ObjArray<lcLibraryCategory>& Categories);
bool lcLoadCategories(lcFile& File, ObjArray<lcLibraryCategory>& Categories);
bool lcSaveCategories(const char* FileName, const ObjArray<lcLibraryCategory>& Categories);
bool lcSaveCategories(lcFile& File, const ObjArray<lcLibraryCategory>& Categories);
#endif // _LC_CATEGORY_H_

File diff suppressed because it is too large Load diff

View file

@ -1,97 +1,97 @@
#ifndef _LC_COLORS_H_
#define _LC_COLORS_H_
#include "opengl.h"
#include "array.h"
#define LC_MAX_COLOR_NAME 64
#define LC_COLOR_DIRECT 0x80000000
struct lcColor
{
lcuint32 Code;
bool Translucent;
float Value[4];
float Edge[4];
char Name[LC_MAX_COLOR_NAME];
char SafeName[LC_MAX_COLOR_NAME];
};
enum
{
LC_COLORGROUP_SOLID,
LC_COLORGROUP_TRANSLUCENT,
LC_COLORGROUP_SPECIAL,
LC_NUM_COLORGROUPS
};
struct lcColorGroup
{
ObjArray<int> Colors;
char Name[LC_MAX_COLOR_NAME];
};
extern ObjArray<lcColor> gColorList;
extern lcColorGroup gColorGroups[LC_NUM_COLORGROUPS];
extern int gNumUserColors;
extern int gEdgeColor;
extern int gDefaultColor;
void lcLoadDefaultColors();
bool lcLoadColorFile(lcFile& File);
int lcGetColorIndex(lcuint32 ColorCode);
int lcGetBrickLinkColor(int ColorIndex);
inline lcuint32 lcGetColorCodeFromExtendedColor(int Color)
{
const int ConverstionTable[] = { 4, 12, 2, 10, 1, 9, 14, 15, 8, 0, 6, 13, 13, 334, 36, 44, 34, 42, 33, 41, 46, 47, 7, 382, 6, 13, 11, 383 };
return ConverstionTable[Color];
}
inline lcuint32 lcGetColorCodeFromOriginalColor(int Color)
{
const int ConverstionTable[] = { 0, 2, 4, 9, 7, 6, 22, 8, 10, 11, 14, 16, 18, 9, 21, 20, 22, 8, 10, 11 };
return lcGetColorCodeFromExtendedColor(ConverstionTable[Color]);
}
inline lcuint32 lcGetColorCode(int ColorIndex)
{
return gColorList[ColorIndex].Code;
}
inline bool lcIsColorTranslucent(int ColorIndex)
{
return gColorList[ColorIndex].Translucent;
}
inline void lcSetColor(int ColorIndex)
{
glColor4fv(gColorList[ColorIndex].Value);
}
inline void lcSetEdgeColor(int ColorIndex)
{
glColor4fv(gColorList[ColorIndex].Edge);
}
inline void lcSetColorFocused()
{
glColor4f(0.4000f, 0.2980f, 0.8980f, 1.0000f);
}
inline void lcSetColorSelected()
{
glColor4f(0.8980f, 0.2980f, 0.4000f, 1.0000f);
}
inline void lcSetColorCamera()
{
glColor4f(0.5f, 0.8f, 0.5f, 1.0f);
}
inline void lcSetColorLight()
{
glColor4f(0.5f, 0.8f, 0.5f, 1.0f);
}
#endif // _LC_COLORS_H_
#ifndef _LC_COLORS_H_
#define _LC_COLORS_H_
#include "opengl.h"
#include "array.h"
#define LC_MAX_COLOR_NAME 64
#define LC_COLOR_DIRECT 0x80000000
struct lcColor
{
lcuint32 Code;
bool Translucent;
float Value[4];
float Edge[4];
char Name[LC_MAX_COLOR_NAME];
char SafeName[LC_MAX_COLOR_NAME];
};
enum
{
LC_COLORGROUP_SOLID,
LC_COLORGROUP_TRANSLUCENT,
LC_COLORGROUP_SPECIAL,
LC_NUM_COLORGROUPS
};
struct lcColorGroup
{
ObjArray<int> Colors;
char Name[LC_MAX_COLOR_NAME];
};
extern ObjArray<lcColor> gColorList;
extern lcColorGroup gColorGroups[LC_NUM_COLORGROUPS];
extern int gNumUserColors;
extern int gEdgeColor;
extern int gDefaultColor;
void lcLoadDefaultColors();
bool lcLoadColorFile(lcFile& File);
int lcGetColorIndex(lcuint32 ColorCode);
int lcGetBrickLinkColor(int ColorIndex);
inline lcuint32 lcGetColorCodeFromExtendedColor(int Color)
{
const int ConverstionTable[] = { 4, 12, 2, 10, 1, 9, 14, 15, 8, 0, 6, 13, 13, 334, 36, 44, 34, 42, 33, 41, 46, 47, 7, 382, 6, 13, 11, 383 };
return ConverstionTable[Color];
}
inline lcuint32 lcGetColorCodeFromOriginalColor(int Color)
{
const int ConverstionTable[] = { 0, 2, 4, 9, 7, 6, 22, 8, 10, 11, 14, 16, 18, 9, 21, 20, 22, 8, 10, 11 };
return lcGetColorCodeFromExtendedColor(ConverstionTable[Color]);
}
inline lcuint32 lcGetColorCode(int ColorIndex)
{
return gColorList[ColorIndex].Code;
}
inline bool lcIsColorTranslucent(int ColorIndex)
{
return gColorList[ColorIndex].Translucent;
}
inline void lcSetColor(int ColorIndex)
{
glColor4fv(gColorList[ColorIndex].Value);
}
inline void lcSetEdgeColor(int ColorIndex)
{
glColor4fv(gColorList[ColorIndex].Edge);
}
inline void lcSetColorFocused()
{
glColor4f(0.4000f, 0.2980f, 0.8980f, 1.0000f);
}
inline void lcSetColorSelected()
{
glColor4f(0.8980f, 0.2980f, 0.4000f, 1.0000f);
}
inline void lcSetColorCamera()
{
glColor4f(0.5f, 0.8f, 0.5f, 1.0f);
}
inline void lcSetColorLight()
{
glColor4f(0.5f, 0.8f, 0.5f, 1.0f);
}
#endif // _LC_COLORS_H_

1206
common/lc_commands.cpp Normal file

File diff suppressed because it is too large Load diff

196
common/lc_commands.h Normal file
View file

@ -0,0 +1,196 @@
#ifndef _LC_COMMANDS_H_
#define _LC_COMMANDS_H_
enum LC_COMMANDS
{
LC_FILE_NEW,
LC_FILE_OPEN,
LC_FILE_MERGE,
LC_FILE_SAVE,
LC_FILE_SAVEAS,
LC_FILE_SAVE_IMAGE,
LC_FILE_EXPORT_3DS,
LC_FILE_EXPORT_HTML,
LC_FILE_EXPORT_BRICKLINK,
LC_FILE_EXPORT_CSV,
LC_FILE_EXPORT_POVRAY,
LC_FILE_EXPORT_WAVEFRONT,
LC_FILE_PROPERTIES,
LC_FILE_TERRAIN_EDITOR,
LC_FILE_PRINT,
LC_FILE_PRINT_PREVIEW,
LC_FILE_PRINT_BOM,
LC_FILE_RECENT_FIRST,
LC_FILE_RECENT1 = LC_FILE_RECENT_FIRST,
LC_FILE_RECENT2,
LC_FILE_RECENT3,
LC_FILE_RECENT4,
LC_FILE_RECENT_LAST = LC_FILE_RECENT4,
LC_FILE_EXIT,
LC_EDIT_UNDO,
LC_EDIT_REDO,
LC_EDIT_CUT,
LC_EDIT_COPY,
LC_EDIT_PASTE,
LC_EDIT_FIND,
LC_EDIT_FIND_NEXT,
LC_EDIT_FIND_PREVIOUS,
LC_EDIT_SELECT_ALL,
LC_EDIT_SELECT_NONE,
LC_EDIT_SELECT_INVERT,
LC_EDIT_SELECT_BY_NAME,
LC_EDIT_LOCK_X,
LC_EDIT_LOCK_Y,
LC_EDIT_LOCK_Z,
LC_EDIT_LOCK_TOGGLE,
LC_EDIT_LOCK_NONE,
LC_EDIT_SNAP_X,
LC_EDIT_SNAP_Y,
LC_EDIT_SNAP_Z,
LC_EDIT_SNAP_TOGGLE,
LC_EDIT_SNAP_NONE,
LC_EDIT_SNAP_ALL,
LC_EDIT_SNAP_ANGLE,
LC_EDIT_SNAP_MOVE_XY0,
LC_EDIT_SNAP_MOVE_XY1,
LC_EDIT_SNAP_MOVE_XY2,
LC_EDIT_SNAP_MOVE_XY3,
LC_EDIT_SNAP_MOVE_XY4,
LC_EDIT_SNAP_MOVE_XY5,
LC_EDIT_SNAP_MOVE_XY6,
LC_EDIT_SNAP_MOVE_XY7,
LC_EDIT_SNAP_MOVE_XY8,
LC_EDIT_SNAP_MOVE_XY9,
LC_EDIT_SNAP_MOVE_Z0,
LC_EDIT_SNAP_MOVE_Z1,
LC_EDIT_SNAP_MOVE_Z2,
LC_EDIT_SNAP_MOVE_Z3,
LC_EDIT_SNAP_MOVE_Z4,
LC_EDIT_SNAP_MOVE_Z5,
LC_EDIT_SNAP_MOVE_Z6,
LC_EDIT_SNAP_MOVE_Z7,
LC_EDIT_SNAP_MOVE_Z8,
LC_EDIT_SNAP_MOVE_Z9,
LC_EDIT_SNAP_ANGLE0,
LC_EDIT_SNAP_ANGLE1,
LC_EDIT_SNAP_ANGLE2,
LC_EDIT_SNAP_ANGLE3,
LC_EDIT_SNAP_ANGLE4,
LC_EDIT_SNAP_ANGLE5,
LC_EDIT_SNAP_ANGLE6,
LC_EDIT_SNAP_ANGLE7,
LC_EDIT_SNAP_ANGLE8,
LC_EDIT_SNAP_ANGLE9,
LC_EDIT_TRANSFORM,
LC_EDIT_TRANSFORM_ABSOLUTE_TRANSLATION,
LC_EDIT_TRANSFORM_RELATIVE_TRANSLATION,
LC_EDIT_TRANSFORM_ABSOLUTE_ROTATION,
LC_EDIT_TRANSFORM_RELATIVE_ROTATION,
LC_EDIT_ACTION_FIRST,
LC_EDIT_ACTION_INSERT = LC_EDIT_ACTION_FIRST,
LC_EDIT_ACTION_LIGHT,
LC_EDIT_ACTION_SPOTLIGHT,
LC_EDIT_ACTION_CAMERA,
LC_EDIT_ACTION_SELECT,
LC_EDIT_ACTION_MOVE,
LC_EDIT_ACTION_ROTATE,
LC_EDIT_ACTION_DELETE,
LC_EDIT_ACTION_PAINT,
LC_EDIT_ACTION_ZOOM,
LC_EDIT_ACTION_PAN,
LC_EDIT_ACTION_ROTATE_VIEW,
LC_EDIT_ACTION_ROLL,
LC_EDIT_ACTION_ZOOM_REGION,
LC_EDIT_ACTION_LAST = LC_EDIT_ACTION_ZOOM_REGION,
LC_EDIT_CANCEL,
LC_VIEW_PREFERENCES,
LC_VIEW_ZOOM_IN,
LC_VIEW_ZOOM_OUT,
LC_VIEW_ZOOM_EXTENTS,
LC_VIEW_VIEWPOINT_FRONT,
LC_VIEW_VIEWPOINT_BACK,
LC_VIEW_VIEWPOINT_TOP,
LC_VIEW_VIEWPOINT_BOTTOM,
LC_VIEW_VIEWPOINT_LEFT,
LC_VIEW_VIEWPOINT_RIGHT,
LC_VIEW_VIEWPOINT_HOME,
LC_VIEW_CAMERA_NONE,
LC_VIEW_CAMERA_FIRST,
LC_VIEW_CAMERA1 = LC_VIEW_CAMERA_FIRST,
LC_VIEW_CAMERA2,
LC_VIEW_CAMERA3,
LC_VIEW_CAMERA4,
LC_VIEW_CAMERA5,
LC_VIEW_CAMERA6,
LC_VIEW_CAMERA7,
LC_VIEW_CAMERA8,
LC_VIEW_CAMERA9,
LC_VIEW_CAMERA10,
LC_VIEW_CAMERA11,
LC_VIEW_CAMERA12,
LC_VIEW_CAMERA13,
LC_VIEW_CAMERA14,
LC_VIEW_CAMERA15,
LC_VIEW_CAMERA16,
LC_VIEW_CAMERA_LAST = LC_VIEW_CAMERA16,
LC_VIEW_CAMERA_RESET,
LC_VIEW_TIME_FIRST,
LC_VIEW_TIME_PREVIOUS,
LC_VIEW_TIME_NEXT,
LC_VIEW_TIME_LAST,
LC_VIEW_TIME_STOP,
LC_VIEW_TIME_PLAY,
LC_VIEW_TIME_INSERT,
LC_VIEW_TIME_DELETE,
LC_VIEW_TIME_ANIMATION,
LC_VIEW_TIME_ADD_KEYS,
LC_VIEW_SPLIT_HORIZONTAL,
LC_VIEW_SPLIT_VERTICAL,
LC_VIEW_REMOVE_VIEW,
LC_VIEW_RESET_VIEWS,
LC_VIEW_FULLSCREEN,
LC_PIECE_INSERT,
LC_PIECE_DELETE,
LC_PIECE_MOVE_PLUSX,
LC_PIECE_MOVE_MINUSX,
LC_PIECE_MOVE_PLUSY,
LC_PIECE_MOVE_MINUSY,
LC_PIECE_MOVE_PLUSZ,
LC_PIECE_MOVE_MINUSZ,
LC_PIECE_ROTATE_PLUSX,
LC_PIECE_ROTATE_MINUSX,
LC_PIECE_ROTATE_PLUSY,
LC_PIECE_ROTATE_MINUSY,
LC_PIECE_ROTATE_PLUSZ,
LC_PIECE_ROTATE_MINUSZ,
LC_PIECE_MINIFIG_WIZARD,
LC_PIECE_ARRAY,
LC_PIECE_COPY_KEYS,
LC_PIECE_GROUP,
LC_PIECE_UNGROUP,
LC_PIECE_GROUP_ADD,
LC_PIECE_GROUP_REMOVE,
LC_PIECE_GROUP_EDIT,
LC_PIECE_HIDE_SELECTED,
LC_PIECE_HIDE_UNSELECTED,
LC_PIECE_UNHIDE_ALL,
LC_PIECE_SHOW_EARLIER,
LC_PIECE_SHOW_LATER,
LC_HELP_HOMEPAGE,
LC_HELP_EMAIL,
LC_HELP_UPDATES,
LC_HELP_ABOUT,
LC_NUM_COMMANDS
};
struct lcCommand
{
const char* ID;
const char* MenuName;
const char* StatusText;
const char* DefaultShortcut;
};
extern lcCommand gCommands[LC_NUM_COMMANDS];
#endif // _LC_COMMANDS_H_

1
common/lc_global.cpp Normal file
View file

@ -0,0 +1 @@
#include "lc_global.h"

View file

@ -1,31 +1,31 @@
#ifndef _LC_GLOBAL_H_
#define _LC_GLOBAL_H_
#include "lc_config.h"
#include "defines.h"
// Version number.
#define LC_VERSION_MAJOR 0
#define LC_VERSION_MINOR 79
#define LC_VERSION_PATCH 4
#define LC_VERSION_TEXT "0.79.4"
// Check for supported platforms.
#if !defined(LC_WINDOWS) && !defined(LC_LINUX)
#error No OS defined.
#endif
// Forward declarations.
class lcVector2;
class lcVector3;
class lcVector4;
class lcMatrix44;
class lcMesh;
class lcTexture;
class lcFile;
class lcMemFile;
class lcDiskFile;
#endif // _LC_GLOBAL_H_
#ifndef _LC_GLOBAL_H_
#define _LC_GLOBAL_H_
#include "lc_config.h"
#include "defines.h"
// Version number.
#define LC_VERSION_MAJOR 0
#define LC_VERSION_MINOR 80
#define LC_VERSION_PATCH 0
#define LC_VERSION_TEXT "0.80.0"
// Check for supported platforms.
#ifndef LC_QT
#error No OS defined.
#endif
// Forward declarations.
class lcVector2;
class lcVector3;
class lcVector4;
class lcMatrix44;
class lcMesh;
class lcTexture;
class lcFile;
class lcMemFile;
class lcDiskFile;
#endif // _LC_GLOBAL_H_

83
common/lc_glwidget.h Normal file
View file

@ -0,0 +1,83 @@
#ifndef _LC_GLWIDGET_H_
#define _LC_GLWIDGET_H_
enum LC_CURSOR_TYPE
{
LC_CURSOR_DEFAULT,
LC_CURSOR_BRICK,
LC_CURSOR_LIGHT,
LC_CURSOR_SPOTLIGHT,
LC_CURSOR_CAMERA,
LC_CURSOR_SELECT,
LC_CURSOR_SELECT_GROUP,
LC_CURSOR_MOVE,
LC_CURSOR_ROTATE,
LC_CURSOR_ROTATEX,
LC_CURSOR_ROTATEY,
LC_CURSOR_DELETE,
LC_CURSOR_PAINT,
LC_CURSOR_ZOOM,
LC_CURSOR_ZOOM_REGION,
LC_CURSOR_PAN,
LC_CURSOR_ROLL,
LC_CURSOR_ROTATE_VIEW,
LC_CURSOR_COUNT
};
struct lcInputState
{
int x;
int y;
bool Control;
bool Shift;
bool Alt;
};
class lcGLWidget
{
public:
lcGLWidget()
{
mCursorType = LC_CURSOR_DEFAULT;
mWidget = NULL;
mInputState.x = 0;
mInputState.y = 0;
mInputState.Control = false;
mInputState.Shift = false;
mInputState.Alt = false;
}
virtual ~lcGLWidget()
{
}
void* GetExtensionAddress(const char* FunctionName);
void ShowPopupMenu();
void MakeCurrent();
void Redraw();
void CaptureMouse();
void ReleaseMouse();
void SetCursor(LC_CURSOR_TYPE Cursor);
virtual void OnDraw() { }
virtual void OnInitialUpdate() { }
virtual void OnUpdateCursor() { }
virtual void OnLeftButtonDown() { }
virtual void OnLeftButtonUp() { }
virtual void OnLeftButtonDoubleClick() { }
virtual void OnMiddleButtonDown() { }
virtual void OnMiddleButtonUp() { }
virtual void OnRightButtonDown() { }
virtual void OnRightButtonUp() { }
virtual void OnMouseMove() { }
virtual void OnMouseWheel(float Direction) { }
lcInputState mInputState;
int mWidth;
int mHeight;
int mCursorType;
void* mWidget;
};
#endif // _LC_GLWIDGET_H_

File diff suppressed because it is too large Load diff

View file

@ -1,174 +1,153 @@
#ifndef _LC_LIBRARY_H_
#define _LC_LIBRARY_H_
#include "lc_mesh.h"
#include "lc_math.h"
#include "array.h"
#include "str.h"
class PieceInfo;
class lcZipFile;
#define LC_CATEGORY_FILE_ID LC_FOURCC('C', 'A', 'T', 0)
#define LC_CATEGORY_FILE_VERSION 0x0100
enum LC_MESH_PRIMITIVE_TYPE
{
LC_MESH_LINES,
LC_MESH_TRIANGLES,
LC_MESH_TEXTURED_LINES,
LC_MESH_TEXTURED_TRIANGLES,
LC_MESH_NUM_PRIMITIVE_TYPES
};
class lcLibraryMeshSection
{
public:
lcLibraryMeshSection(LC_MESH_PRIMITIVE_TYPE PrimitiveType, lcuint32 Color, lcTexture* Texture)
: mIndices(1024, 1024)
{
mPrimitiveType = PrimitiveType;
mColor = Color;
mTexture = Texture;
}
~lcLibraryMeshSection()
{
}
LC_MESH_PRIMITIVE_TYPE mPrimitiveType;
lcuint32 mColor;
lcTexture* mTexture;
ObjArray<lcuint32> mIndices;
};
struct lcLibraryTextureMap
{
lcVector4 Params[2];
lcTexture* Texture;
bool Fallback;
bool Next;
};
class lcLibraryMeshData
{
public:
lcLibraryMeshData()
: mVertices(1024, 1024)
{
}
~lcLibraryMeshData()
{
for (int SectionIdx = 0; SectionIdx < mSections.GetSize(); SectionIdx++)
delete mSections[SectionIdx];
}
void AddLine(int LineType, lcuint32 ColorCode, lcVector3* Vertices);
void AddTexturedLine(int LineType, lcuint32 ColorCode, const lcLibraryTextureMap& Map, lcVector3* Vertices);
void AddMeshData(const lcLibraryMeshData& Data, const lcMatrix44& Transform, lcuint32 CurrentColorCode, lcLibraryTextureMap* TextureMap);
void AddMeshDataNoDuplicateCheck(const lcLibraryMeshData& Data, const lcMatrix44& Transform, lcuint32 CurrentColorCode, lcLibraryTextureMap* TextureMap);
void TestQuad(lcVector3* Vertices);
void ResequenceQuad(lcVector3* Vertices, int a, int b, int c, int d);
PtrArray<lcLibraryMeshSection> mSections;
ObjArray<lcVertex> mVertices;
ObjArray<lcVertexTextured> mTexturedVertices;
};
class lcLibraryPrimitive
{
public:
lcLibraryPrimitive(const char* Name, lcuint32 ZipFileIndex, bool Stud, bool SubFile)
{
strncpy(mName, Name, sizeof(mName));
mName[sizeof(mName) - 1] = 0;
mZipFileIndex = ZipFileIndex;
mLoaded = false;
mStud = Stud;
mSubFile = SubFile;
}
char mName[LC_MAXPATH];
lcuint32 mZipFileIndex;
bool mLoaded;
bool mStud;
bool mSubFile;
lcLibraryMeshData mMeshData;
};
struct lcLibraryCategory
{
String Name;
String Keywords;
};
class lcPiecesLibrary
{
public:
lcPiecesLibrary();
~lcPiecesLibrary();
bool Load(const char* LibraryPath, const char* CachePath);
void Unload();
PieceInfo* FindPiece(const char* PieceName, bool CreatePlaceholderIfMissing);
PieceInfo* CreatePlaceholder(const char* PieceName);
bool LoadPiece(PieceInfo* Info);
bool GeneratePiece(PieceInfo* Info);
void CreateBuiltinPieces();
lcTexture* FindTexture(const char* TextureName);
bool LoadTexture(lcTexture* Texture);
bool OpenCache();
void CloseCache();
bool PieceInCategory(PieceInfo* Info, const String& CategoryKeywords) const;
int GetFirstPieceCategory(PieceInfo* Info) const;
void GetCategoryEntries(int CategoryIndex, bool GroupPieces, PtrArray<PieceInfo>& SinglePieces, PtrArray<PieceInfo>& GroupedPieces);
void GetPatternedPieces(PieceInfo* Parent, PtrArray<PieceInfo>& Pieces) const;
int FindCategoryIndex(const String& CategoryName) const;
void SetCategory(int Index, const String& Name, const String& Keywords);
void AddCategory(const String& Name, const String& Keywords);
void RemoveCategory(int Index);
void ResetCategories();
bool LoadCategories(const char* FileName);
bool SaveCategories();
bool DoSaveCategories(bool AskName);
PtrArray<PieceInfo> mPieces;
PtrArray<lcLibraryPrimitive> mPrimitives;
ObjArray<lcLibraryCategory> mCategories;
int mNumOfficialPieces;
PtrArray<lcTexture> mTextures;
char mLibraryPath[LC_MAXPATH];
protected:
bool OpenArchive(const char* FileName, const char* CachePath);
bool OpenDirectory(const char* Path);
bool LoadCacheIndex(lcZipFile& CacheFile);
bool LoadCachePiece(PieceInfo* Info);
void SaveCacheFile();
int FindPrimitiveIndex(const char* Name);
bool LoadPrimitive(int PrimitiveIndex);
bool ReadMeshData(lcFile& File, const lcMatrix44& CurrentTransform, lcuint32 CurrentColorCode, ObjArray<lcLibraryTextureMap>& TextureStack, lcLibraryMeshData& MeshData);
bool mCategoriesModified;
char mCategoriesFile[LC_MAXPATH];
char mCacheFileName[LC_MAXPATH];
lcuint64 mCacheFileModifiedTime;
lcZipFile* mCacheFile;
bool mSaveCache;
char mLibraryFileName[LC_MAXPATH];
lcZipFile* mZipFile;
};
#endif // _LC_LIBRARY_H_
#ifndef _LC_LIBRARY_H_
#define _LC_LIBRARY_H_
#include "lc_mesh.h"
#include "lc_math.h"
#include "array.h"
#include "str.h"
class PieceInfo;
class lcZipFile;
enum LC_MESH_PRIMITIVE_TYPE
{
LC_MESH_LINES,
LC_MESH_TRIANGLES,
LC_MESH_TEXTURED_LINES,
LC_MESH_TEXTURED_TRIANGLES,
LC_MESH_NUM_PRIMITIVE_TYPES
};
class lcLibraryMeshSection
{
public:
lcLibraryMeshSection(LC_MESH_PRIMITIVE_TYPE PrimitiveType, lcuint32 Color, lcTexture* Texture)
: mIndices(1024, 1024)
{
mPrimitiveType = PrimitiveType;
mColor = Color;
mTexture = Texture;
}
~lcLibraryMeshSection()
{
}
LC_MESH_PRIMITIVE_TYPE mPrimitiveType;
lcuint32 mColor;
lcTexture* mTexture;
ObjArray<lcuint32> mIndices;
};
struct lcLibraryTextureMap
{
lcVector4 Params[2];
lcTexture* Texture;
bool Fallback;
bool Next;
};
class lcLibraryMeshData
{
public:
lcLibraryMeshData()
: mVertices(1024, 1024)
{
}
~lcLibraryMeshData()
{
for (int SectionIdx = 0; SectionIdx < mSections.GetSize(); SectionIdx++)
delete mSections[SectionIdx];
}
void AddLine(int LineType, lcuint32 ColorCode, lcVector3* Vertices);
void AddTexturedLine(int LineType, lcuint32 ColorCode, const lcLibraryTextureMap& Map, lcVector3* Vertices);
void AddMeshData(const lcLibraryMeshData& Data, const lcMatrix44& Transform, lcuint32 CurrentColorCode, lcLibraryTextureMap* TextureMap);
void AddMeshDataNoDuplicateCheck(const lcLibraryMeshData& Data, const lcMatrix44& Transform, lcuint32 CurrentColorCode, lcLibraryTextureMap* TextureMap);
void TestQuad(lcVector3* Vertices);
void ResequenceQuad(lcVector3* Vertices, int a, int b, int c, int d);
PtrArray<lcLibraryMeshSection> mSections;
ObjArray<lcVertex> mVertices;
ObjArray<lcVertexTextured> mTexturedVertices;
};
class lcLibraryPrimitive
{
public:
lcLibraryPrimitive(const char* Name, lcuint32 ZipFileIndex, bool Stud, bool SubFile)
{
strncpy(mName, Name, sizeof(mName));
mName[sizeof(mName) - 1] = 0;
mZipFileIndex = ZipFileIndex;
mLoaded = false;
mStud = Stud;
mSubFile = SubFile;
}
char mName[LC_MAXPATH];
lcuint32 mZipFileIndex;
bool mLoaded;
bool mStud;
bool mSubFile;
lcLibraryMeshData mMeshData;
};
class lcPiecesLibrary
{
public:
lcPiecesLibrary();
~lcPiecesLibrary();
bool Load(const char* LibraryPath, const char* CachePath);
void Unload();
PieceInfo* FindPiece(const char* PieceName, bool CreatePlaceholderIfMissing);
PieceInfo* CreatePlaceholder(const char* PieceName);
bool LoadPiece(PieceInfo* Info);
bool GeneratePiece(PieceInfo* Info);
void CreateBuiltinPieces();
lcTexture* FindTexture(const char* TextureName);
bool LoadTexture(lcTexture* Texture);
bool OpenCache();
void CloseCache();
bool PieceInCategory(PieceInfo* Info, const String& CategoryKeywords) const;
void SearchPieces(const String& CategoryKeywords, bool GroupPieces, PtrArray<PieceInfo>& SinglePieces, PtrArray<PieceInfo>& GroupedPieces);
void GetCategoryEntries(int CategoryIndex, bool GroupPieces, PtrArray<PieceInfo>& SinglePieces, PtrArray<PieceInfo>& GroupedPieces);
void GetPatternedPieces(PieceInfo* Parent, PtrArray<PieceInfo>& Pieces) const;
PtrArray<PieceInfo> mPieces;
PtrArray<lcLibraryPrimitive> mPrimitives;
int mNumOfficialPieces;
PtrArray<lcTexture> mTextures;
char mLibraryPath[LC_MAXPATH];
protected:
bool OpenArchive(const char* FileName, const char* CachePath);
bool OpenDirectory(const char* Path);
bool LoadCacheIndex(lcZipFile& CacheFile);
bool LoadCachePiece(PieceInfo* Info);
void SaveCacheFile();
int FindPrimitiveIndex(const char* Name);
bool LoadPrimitive(int PrimitiveIndex);
bool ReadMeshData(lcFile& File, const lcMatrix44& CurrentTransform, lcuint32 CurrentColorCode, ObjArray<lcLibraryTextureMap>& TextureStack, lcLibraryMeshData& MeshData);
char mCacheFileName[LC_MAXPATH];
lcuint64 mCacheFileModifiedTime;
lcZipFile* mCacheFile;
bool mSaveCache;
char mLibraryFileName[LC_MAXPATH];
lcZipFile* mZipFile;
};
#endif // _LC_LIBRARY_H_

File diff suppressed because it is too large Load diff

View file

@ -1,469 +1,469 @@
#include "lc_global.h"
#include "lc_mesh.h"
#include "lc_colors.h"
#include "lc_texture.h"
#include "lc_file.h"
#include "lc_math.h"
#include "lc_application.h"
#include "lc_library.h"
lcMesh::lcMesh()
{
mSections = NULL;
mNumSections = 0;
mNumVertices = 0;
mNumTexturedVertices = 0;
mIndexType = 0;
}
lcMesh::~lcMesh()
{
delete[] mSections;
}
void lcMesh::Create(int NumSections, int NumVertices, int NumTexturedVertices, int NumIndices)
{
mSections = new lcMeshSection[NumSections];
mNumSections = NumSections;
mNumVertices = NumVertices;
mNumTexturedVertices = NumTexturedVertices;
mVertexBuffer.SetSize(NumVertices * sizeof(lcVertex) + NumTexturedVertices * sizeof(lcVertexTextured));
if (NumVertices < 0x10000 && NumTexturedVertices < 0x10000)
{
mIndexType = GL_UNSIGNED_SHORT;
mIndexBuffer.SetSize(NumIndices * sizeof(GLushort));
}
else
{
mIndexType = GL_UNSIGNED_INT;
mIndexBuffer.SetSize(NumIndices * sizeof(GLuint));
}
}
void lcMesh::CreateBox()
{
Create(2, 8, 0, 36 + 24);
lcVector3 Min(-0.4f, -0.4f, -0.96f);
lcVector3 Max(0.4f, 0.4f, 0.16f);
float* Verts = (float*)mVertexBuffer.mData;
lcuint16* Indices = (lcuint16*)mIndexBuffer.mData;
*Verts++ = Min[0]; *Verts++ = Min[1]; *Verts++ = Min[2];
*Verts++ = Min[0]; *Verts++ = Max[1]; *Verts++ = Min[2];
*Verts++ = Max[0]; *Verts++ = Max[1]; *Verts++ = Min[2];
*Verts++ = Max[0]; *Verts++ = Min[1]; *Verts++ = Min[2];
*Verts++ = Min[0]; *Verts++ = Min[1]; *Verts++ = Max[2];
*Verts++ = Min[0]; *Verts++ = Max[1]; *Verts++ = Max[2];
*Verts++ = Max[0]; *Verts++ = Max[1]; *Verts++ = Max[2];
*Verts++ = Max[0]; *Verts++ = Min[1]; *Verts++ = Max[2];
lcMeshSection* Section = &mSections[0];
Section->ColorIndex = gDefaultColor;
Section->IndexOffset = 0;
Section->NumIndices = 36;
Section->PrimitiveType = GL_TRIANGLES;
Section->Texture = NULL;
*Indices++ = 0; *Indices++ = 1; *Indices++ = 2;
*Indices++ = 0; *Indices++ = 2; *Indices++ = 3;
*Indices++ = 7; *Indices++ = 6; *Indices++ = 5;
*Indices++ = 7; *Indices++ = 5; *Indices++ = 4;
*Indices++ = 0; *Indices++ = 1; *Indices++ = 5;
*Indices++ = 0; *Indices++ = 5; *Indices++ = 4;
*Indices++ = 2; *Indices++ = 3; *Indices++ = 7;
*Indices++ = 2; *Indices++ = 7; *Indices++ = 6;
*Indices++ = 0; *Indices++ = 3; *Indices++ = 7;
*Indices++ = 0; *Indices++ = 7; *Indices++ = 4;
*Indices++ = 1; *Indices++ = 2; *Indices++ = 6;
*Indices++ = 1; *Indices++ = 6; *Indices++ = 5;
Section = &mSections[1];
Section->ColorIndex = gEdgeColor;
Section->IndexOffset = 36 * 2;
Section->NumIndices = 24;
Section->PrimitiveType = GL_LINES;
Section->Texture = NULL;
*Indices++ = 0; *Indices++ = 1; *Indices++ = 1; *Indices++ = 2;
*Indices++ = 2; *Indices++ = 3; *Indices++ = 3; *Indices++ = 0;
*Indices++ = 4; *Indices++ = 5; *Indices++ = 5; *Indices++ = 6;
*Indices++ = 6; *Indices++ = 7; *Indices++ = 7; *Indices++ = 4;
*Indices++ = 0; *Indices++ = 4; *Indices++ = 1; *Indices++ = 5;
*Indices++ = 2; *Indices++ = 6; *Indices++ = 3; *Indices++ = 7;
UpdateBuffers();
}
void lcMesh::Render(int DefaultColorIdx, bool Selected, bool Focused)
{
char* ElementsOffset;
char* BufferOffset;
glEnableClientState(GL_VERTEX_ARRAY);
if (GL_HasVertexBufferObject())
{
glBindBufferARB(GL_ARRAY_BUFFER_ARB, mVertexBuffer.mBuffer);
BufferOffset = NULL;
glBindBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB, mIndexBuffer.mBuffer);
ElementsOffset = NULL;
}
else
{
BufferOffset = (char*)mVertexBuffer.mData;
ElementsOffset = (char*)mIndexBuffer.mData;
}
glVertexPointer(3, GL_FLOAT, 0, BufferOffset);
for (int SectionIdx = 0; SectionIdx < mNumSections; SectionIdx++)
{
lcMeshSection* Section = &mSections[SectionIdx];
int ColorIdx = Section->ColorIndex;
if (Section->PrimitiveType == GL_TRIANGLES)
{
if (ColorIdx == gDefaultColor)
ColorIdx = DefaultColorIdx;
if (lcIsColorTranslucent(ColorIdx))
{
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); // TODO: cache states
glEnable(GL_BLEND);
glDepthMask(GL_FALSE);
}
else
{
glDepthMask(GL_TRUE);
glDisable(GL_BLEND);
}
lcSetColor(ColorIdx);
}
else
{
glDepthMask(GL_TRUE); // TODO: cache states
glDisable(GL_BLEND);
if (Focused)
lcSetColorFocused();
else if (Selected)
lcSetColorSelected();
else if (ColorIdx == gEdgeColor)
lcSetEdgeColor(DefaultColorIdx);
else
lcSetColor(ColorIdx);
}
if (mNumTexturedVertices)
{
if (Section->Texture) // TODO: cache states
{
glVertexPointer(3, GL_FLOAT, sizeof(lcVertexTextured), BufferOffset + (mNumVertices * sizeof(lcVertex)));
glTexCoordPointer(2, GL_FLOAT, sizeof(lcVertexTextured), BufferOffset + ((mNumVertices + 1) * sizeof(lcVertex)));
glEnableClientState(GL_TEXTURE_COORD_ARRAY);
glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_DECAL);
glBindTexture(GL_TEXTURE_2D, Section->Texture->mTexture);
glEnable(GL_TEXTURE_2D);
}
else
{
glDisableClientState(GL_TEXTURE_COORD_ARRAY);
glVertexPointer(3, GL_FLOAT, 0, BufferOffset);
glTexCoordPointer(2, GL_FLOAT, 0, NULL);
glDisable(GL_TEXTURE_2D);
}
}
glDrawElements(Section->PrimitiveType, Section->NumIndices, mIndexType, ElementsOffset + Section->IndexOffset);
}
glDepthMask(GL_TRUE); // TODO: cache states
glDisable(GL_BLEND);
if (GL_HasVertexBufferObject())
{
glBindBufferARB(GL_ARRAY_BUFFER_ARB, 0);
glBindBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB, 0);
}
else
glVertexPointer(3, GL_FLOAT, 0, NULL);
if (mNumTexturedVertices)
{
glDisableClientState(GL_TEXTURE_COORD_ARRAY);
glTexCoordPointer(2, GL_FLOAT, 0, NULL);
glDisable(GL_TEXTURE_2D);
}
glDisableClientState(GL_VERTEX_ARRAY);
}
template<typename IndexType>
bool lcMesh::MinIntersectDist(const lcVector3& Start, const lcVector3& End, float& MinDist, lcVector3& Intersection)
{
float* Verts = (float*)mVertexBuffer.mData;
bool Hit = false;
for (int SectionIdx = 0; SectionIdx < mNumSections; SectionIdx++)
{
lcMeshSection* Section = &mSections[SectionIdx];
if (Section->PrimitiveType != GL_TRIANGLES)
continue;
IndexType* Indices = (IndexType*)mIndexBuffer.mData + Section->IndexOffset / sizeof(IndexType);
for (int Idx = 0; Idx < Section->NumIndices; Idx += 3)
{
float* p1 = Verts + Indices[Idx + 0] * 3;
float* p2 = Verts + Indices[Idx + 1] * 3;
float* p3 = Verts + Indices[Idx + 2] * 3;
lcVector3 v1(p1[0], p1[1], p1[2]);
lcVector3 v2(p2[0], p2[1], p2[2]);
lcVector3 v3(p3[0], p3[1], p3[2]);
if (lcLineTriangleMinIntersection(v1, v2, v3, Start, End, &MinDist, &Intersection))
Hit = true;
}
}
return Hit;
}
bool lcMesh::MinIntersectDist(const lcVector3& Start, const lcVector3& End, float& MinDist, lcVector3& Intersection)
{
if (mIndexType == GL_UNSIGNED_SHORT)
return MinIntersectDist<GLushort>(Start, End, MinDist, Intersection);
else
return MinIntersectDist<GLuint>(Start, End, MinDist, Intersection);
}
template<typename IndexType>
bool lcMesh::IntersectsPlanes(const lcVector4 Planes[6])
{
float* Verts = (float*)mVertexBuffer.mData;
for (int SectionIdx = 0; SectionIdx < mNumSections; SectionIdx++)
{
lcMeshSection* Section = &mSections[SectionIdx];
if (Section->PrimitiveType != GL_TRIANGLES)
continue;
IndexType* Indices = (IndexType*)mIndexBuffer.mData + Section->IndexOffset / sizeof(IndexType);
for (int Idx = 0; Idx < Section->NumIndices; Idx += 3)
if (lcTriangleIntersectsPlanes(&Verts[Indices[Idx]*3], &Verts[Indices[Idx+1]*3], &Verts[Indices[Idx+2]*3], Planes))
return true;
}
return false;
}
bool lcMesh::IntersectsPlanes(const lcVector4 Planes[6])
{
if (mIndexType == GL_UNSIGNED_SHORT)
return IntersectsPlanes<GLushort>(Planes);
else
return IntersectsPlanes<GLuint>(Planes);
}
template<typename IndexType>
void lcMesh::ExportPOVRay(lcFile& File, const char* MeshName, const char* ColorTable)
{
char Line[1024];
sprintf(Line, "#declare lc_%s = union {\n", MeshName);
File.WriteLine(Line);
float* Verts = (float*)mVertexBuffer.mData;
for (int SectionIdx = 0; SectionIdx < mNumSections; SectionIdx++)
{
lcMeshSection* Section = &mSections[SectionIdx];
if (Section->PrimitiveType != GL_TRIANGLES)
continue;
IndexType* Indices = (IndexType*)mIndexBuffer.mData + Section->IndexOffset / sizeof(IndexType);
File.WriteLine(" mesh {\n");
for (int Idx = 0; Idx < Section->NumIndices; Idx += 3)
{
sprintf(Line, " triangle { <%.2f, %.2f, %.2f>, <%.2f, %.2f, %.2f>, <%.2f, %.2f, %.2f> }\n",
-Verts[Indices[Idx+0]*3+1], -Verts[Indices[Idx+0]*3], Verts[Indices[Idx+0]*3+2],
-Verts[Indices[Idx+1]*3+1], -Verts[Indices[Idx+1]*3], Verts[Indices[Idx+1]*3+2],
-Verts[Indices[Idx+2]*3+1], -Verts[Indices[Idx+2]*3], Verts[Indices[Idx+2]*3+2]);
File.WriteLine(Line);
}
if (Section->ColorIndex != gDefaultColor)
{
sprintf(Line, "material { texture { %s normal { bumps 0.1 scale 2 } } }", &ColorTable[Section->ColorIndex * LC_MAX_COLOR_NAME]);
File.WriteLine(Line);
}
File.WriteLine(" }\n");
}
}
void lcMesh::ExportPOVRay(lcFile& File, const char* MeshName, const char* ColorTable)
{
if (mIndexType == GL_UNSIGNED_SHORT)
ExportPOVRay<GLushort>(File, MeshName, ColorTable);
else
ExportPOVRay<GLuint>(File, MeshName, ColorTable);
}
template<typename IndexType>
void lcMesh::ExportWavefrontIndices(lcFile& File, int DefaultColorIndex, int VertexOffset)
{
char Line[1024];
for (int SectionIdx = 0; SectionIdx < mNumSections; SectionIdx++)
{
lcMeshSection* Section = &mSections[SectionIdx];
if (Section->PrimitiveType != GL_TRIANGLES)
continue;
IndexType* Indices = (IndexType*)mIndexBuffer.mData + Section->IndexOffset / sizeof(IndexType);
if (Section->ColorIndex == gDefaultColor)
sprintf(Line, "usemtl %s\n", gColorList[DefaultColorIndex].SafeName);
else
sprintf(Line, "usemtl %s\n", gColorList[Section->ColorIndex].SafeName);
File.WriteLine(Line);
for (int Idx = 0; Idx < Section->NumIndices; Idx += 3)
{
long int idx1 = Indices[Idx + 0] + VertexOffset;
long int idx2 = Indices[Idx + 1] + VertexOffset;
long int idx3 = Indices[Idx + 2] + VertexOffset;
if (idx1 != idx2 && idx1 != idx3 && idx2 != idx3)
sprintf(Line, "f %ld %ld %ld\n", idx1, idx2, idx3);
File.WriteLine(Line);
}
}
File.WriteLine("\n");
}
void lcMesh::ExportWavefrontIndices(lcFile& File, int DefaultColorIndex, int VertexOffset)
{
if (mIndexType == GL_UNSIGNED_SHORT)
ExportWavefrontIndices<GLushort>(File, DefaultColorIndex, VertexOffset);
else
ExportWavefrontIndices<GLuint>(File, DefaultColorIndex, VertexOffset);
}
bool lcMesh::FileLoad(lcFile& File)
{
if (File.ReadU32() != LC_FILE_ID || File.ReadU32() != LC_MESH_FILE_ID || File.ReadU32() != LC_MESH_FILE_VERSION)
return false;
lcuint32 NumVertices, NumTexturedVertices, NumIndices;
lcuint16 NumSections;
if (!File.ReadU16(&NumSections, 1) || !File.ReadU32(&NumVertices, 1) || !File.ReadU32(&NumTexturedVertices, 1) || !File.ReadU32(&NumIndices, 1))
return false;
Create(NumSections, NumVertices, NumTexturedVertices, NumIndices);
for (int SectionIdx = 0; SectionIdx < mNumSections; SectionIdx++)
{
lcMeshSection& Section = mSections[SectionIdx];
lcuint32 ColorCode, IndexOffset;
lcuint16 Triangles, Length;
if (!File.ReadU32(&ColorCode, 1) || !File.ReadU32(&IndexOffset, 1) || !File.ReadU32(&NumIndices, 1) || !File.ReadU16(&Triangles, 1))
return false;
Section.ColorIndex = lcGetColorIndex(ColorCode);
Section.IndexOffset = IndexOffset;
Section.NumIndices = NumIndices;
Section.PrimitiveType = Triangles ? GL_TRIANGLES : GL_LINES;
if (!File.ReadU16(&Length, 1))
return false;
if (Length)
{
if (Length >= LC_TEXTURE_NAME_LEN)
return false;
char FileName[LC_TEXTURE_NAME_LEN];
File.ReadBuffer(FileName, Length);
FileName[Length] = 0;
Section.Texture = lcGetPiecesLibrary()->FindTexture(FileName);
}
else
Section.Texture = NULL;
}
File.ReadFloats((float*)mVertexBuffer.mData, 3 * mNumVertices + 5 * mNumTexturedVertices);
if (mIndexType == GL_UNSIGNED_SHORT)
File.ReadU16((lcuint16*)mIndexBuffer.mData, mIndexBuffer.mSize / 2);
else
File.ReadU32((lcuint32*)mIndexBuffer.mData, mIndexBuffer.mSize / 4);
UpdateBuffers();
return true;
}
void lcMesh::FileSave(lcFile& File)
{
File.WriteU32(LC_FILE_ID);
File.WriteU32(LC_MESH_FILE_ID);
File.WriteU32(LC_MESH_FILE_VERSION);
File.WriteU16(mNumSections);
File.WriteU32(mNumVertices);
File.WriteU32(mNumTexturedVertices);
File.WriteU32(mIndexBuffer.mSize / (mIndexType == GL_UNSIGNED_SHORT ? 2 : 4));
for (int SectionIdx = 0; SectionIdx < mNumSections; SectionIdx++)
{
lcMeshSection& Section = mSections[SectionIdx];
File.WriteU32(lcGetColorCode(Section.ColorIndex));
File.WriteU32(Section.IndexOffset);
File.WriteU32(Section.NumIndices);
File.WriteU16(Section.PrimitiveType == GL_TRIANGLES ? 1 : 0);
if (Section.Texture)
{
int Length = strlen(Section.Texture->mName);
File.WriteU16(Length);
File.WriteBuffer(Section.Texture->mName, Length);
}
else
File.WriteU16(0);
}
File.WriteFloats((float*)mVertexBuffer.mData, 3 * mNumVertices + 5 * mNumTexturedVertices);
if (mIndexType == GL_UNSIGNED_SHORT)
File.WriteU16((lcuint16*)mIndexBuffer.mData, mIndexBuffer.mSize / 2);
else
File.WriteU32((lcuint32*)mIndexBuffer.mData, mIndexBuffer.mSize / 4);
}
#include "lc_global.h"
#include "lc_mesh.h"
#include "lc_colors.h"
#include "lc_texture.h"
#include "lc_file.h"
#include "lc_math.h"
#include "lc_application.h"
#include "lc_library.h"
lcMesh::lcMesh()
{
mSections = NULL;
mNumSections = 0;
mNumVertices = 0;
mNumTexturedVertices = 0;
mIndexType = 0;
}
lcMesh::~lcMesh()
{
delete[] mSections;
}
void lcMesh::Create(int NumSections, int NumVertices, int NumTexturedVertices, int NumIndices)
{
mSections = new lcMeshSection[NumSections];
mNumSections = NumSections;
mNumVertices = NumVertices;
mNumTexturedVertices = NumTexturedVertices;
mVertexBuffer.SetSize(NumVertices * sizeof(lcVertex) + NumTexturedVertices * sizeof(lcVertexTextured));
if (NumVertices < 0x10000 && NumTexturedVertices < 0x10000)
{
mIndexType = GL_UNSIGNED_SHORT;
mIndexBuffer.SetSize(NumIndices * sizeof(GLushort));
}
else
{
mIndexType = GL_UNSIGNED_INT;
mIndexBuffer.SetSize(NumIndices * sizeof(GLuint));
}
}
void lcMesh::CreateBox()
{
Create(2, 8, 0, 36 + 24);
lcVector3 Min(-0.4f, -0.4f, -0.96f);
lcVector3 Max(0.4f, 0.4f, 0.16f);
float* Verts = (float*)mVertexBuffer.mData;
lcuint16* Indices = (lcuint16*)mIndexBuffer.mData;
*Verts++ = Min[0]; *Verts++ = Min[1]; *Verts++ = Min[2];
*Verts++ = Min[0]; *Verts++ = Max[1]; *Verts++ = Min[2];
*Verts++ = Max[0]; *Verts++ = Max[1]; *Verts++ = Min[2];
*Verts++ = Max[0]; *Verts++ = Min[1]; *Verts++ = Min[2];
*Verts++ = Min[0]; *Verts++ = Min[1]; *Verts++ = Max[2];
*Verts++ = Min[0]; *Verts++ = Max[1]; *Verts++ = Max[2];
*Verts++ = Max[0]; *Verts++ = Max[1]; *Verts++ = Max[2];
*Verts++ = Max[0]; *Verts++ = Min[1]; *Verts++ = Max[2];
lcMeshSection* Section = &mSections[0];
Section->ColorIndex = gDefaultColor;
Section->IndexOffset = 0;
Section->NumIndices = 36;
Section->PrimitiveType = GL_TRIANGLES;
Section->Texture = NULL;
*Indices++ = 0; *Indices++ = 1; *Indices++ = 2;
*Indices++ = 0; *Indices++ = 2; *Indices++ = 3;
*Indices++ = 7; *Indices++ = 6; *Indices++ = 5;
*Indices++ = 7; *Indices++ = 5; *Indices++ = 4;
*Indices++ = 0; *Indices++ = 1; *Indices++ = 5;
*Indices++ = 0; *Indices++ = 5; *Indices++ = 4;
*Indices++ = 2; *Indices++ = 3; *Indices++ = 7;
*Indices++ = 2; *Indices++ = 7; *Indices++ = 6;
*Indices++ = 0; *Indices++ = 3; *Indices++ = 7;
*Indices++ = 0; *Indices++ = 7; *Indices++ = 4;
*Indices++ = 1; *Indices++ = 2; *Indices++ = 6;
*Indices++ = 1; *Indices++ = 6; *Indices++ = 5;
Section = &mSections[1];
Section->ColorIndex = gEdgeColor;
Section->IndexOffset = 36 * 2;
Section->NumIndices = 24;
Section->PrimitiveType = GL_LINES;
Section->Texture = NULL;
*Indices++ = 0; *Indices++ = 1; *Indices++ = 1; *Indices++ = 2;
*Indices++ = 2; *Indices++ = 3; *Indices++ = 3; *Indices++ = 0;
*Indices++ = 4; *Indices++ = 5; *Indices++ = 5; *Indices++ = 6;
*Indices++ = 6; *Indices++ = 7; *Indices++ = 7; *Indices++ = 4;
*Indices++ = 0; *Indices++ = 4; *Indices++ = 1; *Indices++ = 5;
*Indices++ = 2; *Indices++ = 6; *Indices++ = 3; *Indices++ = 7;
UpdateBuffers();
}
void lcMesh::Render(int DefaultColorIdx, bool Selected, bool Focused)
{
char* ElementsOffset;
char* BufferOffset;
glEnableClientState(GL_VERTEX_ARRAY);
if (GL_HasVertexBufferObject())
{
glBindBuffer(GL_ARRAY_BUFFER_ARB, mVertexBuffer.mBuffer);
BufferOffset = NULL;
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER_ARB, mIndexBuffer.mBuffer);
ElementsOffset = NULL;
}
else
{
BufferOffset = (char*)mVertexBuffer.mData;
ElementsOffset = (char*)mIndexBuffer.mData;
}
glVertexPointer(3, GL_FLOAT, 0, BufferOffset);
for (int SectionIdx = 0; SectionIdx < mNumSections; SectionIdx++)
{
lcMeshSection* Section = &mSections[SectionIdx];
int ColorIdx = Section->ColorIndex;
if (Section->PrimitiveType == GL_TRIANGLES)
{
if (ColorIdx == gDefaultColor)
ColorIdx = DefaultColorIdx;
if (lcIsColorTranslucent(ColorIdx))
{
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); // TODO: cache states
glEnable(GL_BLEND);
glDepthMask(GL_FALSE);
}
else
{
glDepthMask(GL_TRUE);
glDisable(GL_BLEND);
}
lcSetColor(ColorIdx);
}
else
{
glDepthMask(GL_TRUE); // TODO: cache states
glDisable(GL_BLEND);
if (Focused)
lcSetColorFocused();
else if (Selected)
lcSetColorSelected();
else if (ColorIdx == gEdgeColor)
lcSetEdgeColor(DefaultColorIdx);
else
lcSetColor(ColorIdx);
}
if (mNumTexturedVertices)
{
if (Section->Texture) // TODO: cache states
{
glVertexPointer(3, GL_FLOAT, sizeof(lcVertexTextured), BufferOffset + (mNumVertices * sizeof(lcVertex)));
glTexCoordPointer(2, GL_FLOAT, sizeof(lcVertexTextured), BufferOffset + ((mNumVertices + 1) * sizeof(lcVertex)));
glEnableClientState(GL_TEXTURE_COORD_ARRAY);
glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_DECAL);
glBindTexture(GL_TEXTURE_2D, Section->Texture->mTexture);
glEnable(GL_TEXTURE_2D);
}
else
{
glDisableClientState(GL_TEXTURE_COORD_ARRAY);
glVertexPointer(3, GL_FLOAT, 0, BufferOffset);
glTexCoordPointer(2, GL_FLOAT, 0, NULL);
glDisable(GL_TEXTURE_2D);
}
}
glDrawElements(Section->PrimitiveType, Section->NumIndices, mIndexType, ElementsOffset + Section->IndexOffset);
}
glDepthMask(GL_TRUE); // TODO: cache states
glDisable(GL_BLEND);
if (GL_HasVertexBufferObject())
{
glBindBuffer(GL_ARRAY_BUFFER_ARB, 0);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER_ARB, 0);
}
else
glVertexPointer(3, GL_FLOAT, 0, NULL);
if (mNumTexturedVertices)
{
glDisableClientState(GL_TEXTURE_COORD_ARRAY);
glTexCoordPointer(2, GL_FLOAT, 0, NULL);
glDisable(GL_TEXTURE_2D);
}
glDisableClientState(GL_VERTEX_ARRAY);
}
template<typename IndexType>
bool lcMesh::MinIntersectDist(const lcVector3& Start, const lcVector3& End, float& MinDist, lcVector3& Intersection)
{
float* Verts = (float*)mVertexBuffer.mData;
bool Hit = false;
for (int SectionIdx = 0; SectionIdx < mNumSections; SectionIdx++)
{
lcMeshSection* Section = &mSections[SectionIdx];
if (Section->PrimitiveType != GL_TRIANGLES)
continue;
IndexType* Indices = (IndexType*)mIndexBuffer.mData + Section->IndexOffset / sizeof(IndexType);
for (int Idx = 0; Idx < Section->NumIndices; Idx += 3)
{
float* p1 = Verts + Indices[Idx + 0] * 3;
float* p2 = Verts + Indices[Idx + 1] * 3;
float* p3 = Verts + Indices[Idx + 2] * 3;
lcVector3 v1(p1[0], p1[1], p1[2]);
lcVector3 v2(p2[0], p2[1], p2[2]);
lcVector3 v3(p3[0], p3[1], p3[2]);
if (lcLineTriangleMinIntersection(v1, v2, v3, Start, End, &MinDist, &Intersection))
Hit = true;
}
}
return Hit;
}
bool lcMesh::MinIntersectDist(const lcVector3& Start, const lcVector3& End, float& MinDist, lcVector3& Intersection)
{
if (mIndexType == GL_UNSIGNED_SHORT)
return MinIntersectDist<GLushort>(Start, End, MinDist, Intersection);
else
return MinIntersectDist<GLuint>(Start, End, MinDist, Intersection);
}
template<typename IndexType>
bool lcMesh::IntersectsPlanes(const lcVector4 Planes[6])
{
float* Verts = (float*)mVertexBuffer.mData;
for (int SectionIdx = 0; SectionIdx < mNumSections; SectionIdx++)
{
lcMeshSection* Section = &mSections[SectionIdx];
if (Section->PrimitiveType != GL_TRIANGLES)
continue;
IndexType* Indices = (IndexType*)mIndexBuffer.mData + Section->IndexOffset / sizeof(IndexType);
for (int Idx = 0; Idx < Section->NumIndices; Idx += 3)
if (lcTriangleIntersectsPlanes(&Verts[Indices[Idx]*3], &Verts[Indices[Idx+1]*3], &Verts[Indices[Idx+2]*3], Planes))
return true;
}
return false;
}
bool lcMesh::IntersectsPlanes(const lcVector4 Planes[6])
{
if (mIndexType == GL_UNSIGNED_SHORT)
return IntersectsPlanes<GLushort>(Planes);
else
return IntersectsPlanes<GLuint>(Planes);
}
template<typename IndexType>
void lcMesh::ExportPOVRay(lcFile& File, const char* MeshName, const char* ColorTable)
{
char Line[1024];
sprintf(Line, "#declare lc_%s = union {\n", MeshName);
File.WriteLine(Line);
float* Verts = (float*)mVertexBuffer.mData;
for (int SectionIdx = 0; SectionIdx < mNumSections; SectionIdx++)
{
lcMeshSection* Section = &mSections[SectionIdx];
if (Section->PrimitiveType != GL_TRIANGLES)
continue;
IndexType* Indices = (IndexType*)mIndexBuffer.mData + Section->IndexOffset / sizeof(IndexType);
File.WriteLine(" mesh {\n");
for (int Idx = 0; Idx < Section->NumIndices; Idx += 3)
{
sprintf(Line, " triangle { <%.2f, %.2f, %.2f>, <%.2f, %.2f, %.2f>, <%.2f, %.2f, %.2f> }\n",
-Verts[Indices[Idx+0]*3+1], -Verts[Indices[Idx+0]*3], Verts[Indices[Idx+0]*3+2],
-Verts[Indices[Idx+1]*3+1], -Verts[Indices[Idx+1]*3], Verts[Indices[Idx+1]*3+2],
-Verts[Indices[Idx+2]*3+1], -Verts[Indices[Idx+2]*3], Verts[Indices[Idx+2]*3+2]);
File.WriteLine(Line);
}
if (Section->ColorIndex != gDefaultColor)
{
sprintf(Line, "material { texture { %s normal { bumps 0.1 scale 2 } } }", &ColorTable[Section->ColorIndex * LC_MAX_COLOR_NAME]);
File.WriteLine(Line);
}
File.WriteLine(" }\n");
}
}
void lcMesh::ExportPOVRay(lcFile& File, const char* MeshName, const char* ColorTable)
{
if (mIndexType == GL_UNSIGNED_SHORT)
ExportPOVRay<GLushort>(File, MeshName, ColorTable);
else
ExportPOVRay<GLuint>(File, MeshName, ColorTable);
}
template<typename IndexType>
void lcMesh::ExportWavefrontIndices(lcFile& File, int DefaultColorIndex, int VertexOffset)
{
char Line[1024];
for (int SectionIdx = 0; SectionIdx < mNumSections; SectionIdx++)
{
lcMeshSection* Section = &mSections[SectionIdx];
if (Section->PrimitiveType != GL_TRIANGLES)
continue;
IndexType* Indices = (IndexType*)mIndexBuffer.mData + Section->IndexOffset / sizeof(IndexType);
if (Section->ColorIndex == gDefaultColor)
sprintf(Line, "usemtl %s\n", gColorList[DefaultColorIndex].SafeName);
else
sprintf(Line, "usemtl %s\n", gColorList[Section->ColorIndex].SafeName);
File.WriteLine(Line);
for (int Idx = 0; Idx < Section->NumIndices; Idx += 3)
{
long int idx1 = Indices[Idx + 0] + VertexOffset;
long int idx2 = Indices[Idx + 1] + VertexOffset;
long int idx3 = Indices[Idx + 2] + VertexOffset;
if (idx1 != idx2 && idx1 != idx3 && idx2 != idx3)
sprintf(Line, "f %ld %ld %ld\n", idx1, idx2, idx3);
File.WriteLine(Line);
}
}
File.WriteLine("\n");
}
void lcMesh::ExportWavefrontIndices(lcFile& File, int DefaultColorIndex, int VertexOffset)
{
if (mIndexType == GL_UNSIGNED_SHORT)
ExportWavefrontIndices<GLushort>(File, DefaultColorIndex, VertexOffset);
else
ExportWavefrontIndices<GLuint>(File, DefaultColorIndex, VertexOffset);
}
bool lcMesh::FileLoad(lcFile& File)
{
if (File.ReadU32() != LC_FILE_ID || File.ReadU32() != LC_MESH_FILE_ID || File.ReadU32() != LC_MESH_FILE_VERSION)
return false;
lcuint32 NumVertices, NumTexturedVertices, NumIndices;
lcuint16 NumSections;
if (!File.ReadU16(&NumSections, 1) || !File.ReadU32(&NumVertices, 1) || !File.ReadU32(&NumTexturedVertices, 1) || !File.ReadU32(&NumIndices, 1))
return false;
Create(NumSections, NumVertices, NumTexturedVertices, NumIndices);
for (int SectionIdx = 0; SectionIdx < mNumSections; SectionIdx++)
{
lcMeshSection& Section = mSections[SectionIdx];
lcuint32 ColorCode, IndexOffset;
lcuint16 Triangles, Length;
if (!File.ReadU32(&ColorCode, 1) || !File.ReadU32(&IndexOffset, 1) || !File.ReadU32(&NumIndices, 1) || !File.ReadU16(&Triangles, 1))
return false;
Section.ColorIndex = lcGetColorIndex(ColorCode);
Section.IndexOffset = IndexOffset;
Section.NumIndices = NumIndices;
Section.PrimitiveType = Triangles ? GL_TRIANGLES : GL_LINES;
if (!File.ReadU16(&Length, 1))
return false;
if (Length)
{
if (Length >= LC_TEXTURE_NAME_LEN)
return false;
char FileName[LC_TEXTURE_NAME_LEN];
File.ReadBuffer(FileName, Length);
FileName[Length] = 0;
Section.Texture = lcGetPiecesLibrary()->FindTexture(FileName);
}
else
Section.Texture = NULL;
}
File.ReadFloats((float*)mVertexBuffer.mData, 3 * mNumVertices + 5 * mNumTexturedVertices);
if (mIndexType == GL_UNSIGNED_SHORT)
File.ReadU16((lcuint16*)mIndexBuffer.mData, mIndexBuffer.mSize / 2);
else
File.ReadU32((lcuint32*)mIndexBuffer.mData, mIndexBuffer.mSize / 4);
UpdateBuffers();
return true;
}
void lcMesh::FileSave(lcFile& File)
{
File.WriteU32(LC_FILE_ID);
File.WriteU32(LC_MESH_FILE_ID);
File.WriteU32(LC_MESH_FILE_VERSION);
File.WriteU16(mNumSections);
File.WriteU32(mNumVertices);
File.WriteU32(mNumTexturedVertices);
File.WriteU32(mIndexBuffer.mSize / (mIndexType == GL_UNSIGNED_SHORT ? 2 : 4));
for (int SectionIdx = 0; SectionIdx < mNumSections; SectionIdx++)
{
lcMeshSection& Section = mSections[SectionIdx];
File.WriteU32(lcGetColorCode(Section.ColorIndex));
File.WriteU32(Section.IndexOffset);
File.WriteU32(Section.NumIndices);
File.WriteU16(Section.PrimitiveType == GL_TRIANGLES ? 1 : 0);
if (Section.Texture)
{
int Length = strlen(Section.Texture->mName);
File.WriteU16(Length);
File.WriteBuffer(Section.Texture->mName, Length);
}
else
File.WriteU16(0);
}
File.WriteFloats((float*)mVertexBuffer.mData, 3 * mNumVertices + 5 * mNumTexturedVertices);
if (mIndexType == GL_UNSIGNED_SHORT)
File.WriteU16((lcuint16*)mIndexBuffer.mData, mIndexBuffer.mSize / 2);
else
File.WriteU32((lcuint32*)mIndexBuffer.mData, mIndexBuffer.mSize / 4);
}

View file

@ -1,169 +1,169 @@
#ifndef _LC_MESH_H_
#define _LC_MESH_H_
#include <stdlib.h>
#include "opengl.h"
#include "lc_math.h"
#define LC_MESH_FILE_ID LC_FOURCC('M', 'E', 'S', 'H')
#define LC_MESH_FILE_VERSION 0x0100
struct lcVertex
{
lcVector3 Position;
};
struct lcVertexTextured
{
lcVector3 Position;
lcVector2 TexCoord;
};
class lcVertexBuffer
{
public:
lcVertexBuffer()
{
mData = NULL;
mSize = 0;
mBuffer = 0;
}
~lcVertexBuffer()
{
if (mBuffer)
{
glBindBufferARB(GL_ARRAY_BUFFER_ARB, 0);
glDeleteBuffersARB(1, &mBuffer);
}
free(mData);
}
void SetSize(int Size)
{
free(mData);
mData = malloc(Size);
mSize = Size;
}
void UpdateBuffer()
{
if (!GL_HasVertexBufferObject())
return;
if (!mBuffer)
glGenBuffersARB(1, &mBuffer);
glBindBufferARB(GL_ARRAY_BUFFER_ARB, mBuffer);
glBufferDataARB(GL_ARRAY_BUFFER_ARB, mSize, mData, GL_STATIC_DRAW_ARB);
glBindBufferARB(GL_ARRAY_BUFFER_ARB, 0);
}
void* mData;
int mSize;
GLuint mBuffer;
};
class lcIndexBuffer
{
public:
lcIndexBuffer()
{
mData = NULL;
mSize = 0;
mBuffer = 0;
}
~lcIndexBuffer()
{
if (mBuffer)
{
glBindBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB, 0);
glDeleteBuffersARB(1, &mBuffer);
}
free(mData);
}
void SetSize(int Size)
{
free(mData);
mData = malloc(Size);
mSize = Size;
}
void UpdateBuffer()
{
if (!GL_HasVertexBufferObject())
return;
if (!mBuffer)
glGenBuffersARB(1, &mBuffer);
glBindBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB, mBuffer);
glBufferDataARB(GL_ELEMENT_ARRAY_BUFFER_ARB, mSize, mData, GL_STATIC_DRAW_ARB);
glBindBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB, 0);
}
void* mData;
int mSize;
GLuint mBuffer;
};
struct lcMeshSection
{
int ColorIndex;
int IndexOffset;
int NumIndices;
int PrimitiveType;
lcTexture* Texture;
// BoundingBox Box;
};
class lcMesh
{
public:
lcMesh();
~lcMesh();
void Create(int NumSections, int NumVertices, int NumTexturedVertices, int NumIndices);
void CreateBox();
void Render(int ColorIdx, bool Selected, bool Focused);
bool FileLoad(lcFile& File);
void FileSave(lcFile& File);
template<typename IndexType>
void ExportPOVRay(lcFile& File, const char* MeshName, const char* ColorTable);
void ExportPOVRay(lcFile& File, const char* MeshName, const char* ColorTable);
template<typename IndexType>
void ExportWavefrontIndices(lcFile& File, int DefaultColorIndex, int VertexOffset);
void ExportWavefrontIndices(lcFile& File, int DefaultColorIndex, int VertexOffset);
template<typename IndexType>
bool MinIntersectDist(const lcVector3& Start, const lcVector3& End, float& MinDist, lcVector3& Intersection);
bool MinIntersectDist(const lcVector3& Start, const lcVector3& End, float& MinDist, lcVector3& Intersection);
template<typename IndexType>
bool IntersectsPlanes(const lcVector4 Planes[6]);
bool IntersectsPlanes(const lcVector4 Planes[6]);
void UpdateBuffers()
{
mVertexBuffer.UpdateBuffer();
mIndexBuffer.UpdateBuffer();
}
lcMeshSection* mSections;
int mNumSections;
lcVertexBuffer mVertexBuffer;
lcIndexBuffer mIndexBuffer;
int mNumVertices;
int mNumTexturedVertices;
int mIndexType;
};
#endif // _LC_MESH_H_
#ifndef _LC_MESH_H_
#define _LC_MESH_H_
#include <stdlib.h>
#include "opengl.h"
#include "lc_math.h"
#define LC_MESH_FILE_ID LC_FOURCC('M', 'E', 'S', 'H')
#define LC_MESH_FILE_VERSION 0x0100
struct lcVertex
{
lcVector3 Position;
};
struct lcVertexTextured
{
lcVector3 Position;
lcVector2 TexCoord;
};
class lcVertexBuffer
{
public:
lcVertexBuffer()
{
mData = NULL;
mSize = 0;
mBuffer = 0;
}
~lcVertexBuffer()
{
if (mBuffer)
{
glBindBuffer(GL_ARRAY_BUFFER_ARB, 0);
glDeleteBuffers(1, &mBuffer);
}
free(mData);
}
void SetSize(int Size)
{
free(mData);
mData = malloc(Size);
mSize = Size;
}
void UpdateBuffer()
{
if (!GL_HasVertexBufferObject())
return;
if (!mBuffer)
glGenBuffers(1, &mBuffer);
glBindBuffer(GL_ARRAY_BUFFER_ARB, mBuffer);
glBufferData(GL_ARRAY_BUFFER_ARB, mSize, mData, GL_STATIC_DRAW_ARB);
glBindBuffer(GL_ARRAY_BUFFER_ARB, 0);
}
void* mData;
int mSize;
GLuint mBuffer;
};
class lcIndexBuffer
{
public:
lcIndexBuffer()
{
mData = NULL;
mSize = 0;
mBuffer = 0;
}
~lcIndexBuffer()
{
if (mBuffer)
{
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER_ARB, 0);
glDeleteBuffers(1, &mBuffer);
}
free(mData);
}
void SetSize(int Size)
{
free(mData);
mData = malloc(Size);
mSize = Size;
}
void UpdateBuffer()
{
if (!GL_HasVertexBufferObject())
return;
if (!mBuffer)
glGenBuffers(1, &mBuffer);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER_ARB, mBuffer);
glBufferData(GL_ELEMENT_ARRAY_BUFFER_ARB, mSize, mData, GL_STATIC_DRAW_ARB);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER_ARB, 0);
}
void* mData;
int mSize;
GLuint mBuffer;
};
struct lcMeshSection
{
int ColorIndex;
int IndexOffset;
int NumIndices;
int PrimitiveType;
lcTexture* Texture;
// BoundingBox Box;
};
class lcMesh
{
public:
lcMesh();
~lcMesh();
void Create(int NumSections, int NumVertices, int NumTexturedVertices, int NumIndices);
void CreateBox();
void Render(int ColorIdx, bool Selected, bool Focused);
bool FileLoad(lcFile& File);
void FileSave(lcFile& File);
template<typename IndexType>
void ExportPOVRay(lcFile& File, const char* MeshName, const char* ColorTable);
void ExportPOVRay(lcFile& File, const char* MeshName, const char* ColorTable);
template<typename IndexType>
void ExportWavefrontIndices(lcFile& File, int DefaultColorIndex, int VertexOffset);
void ExportWavefrontIndices(lcFile& File, int DefaultColorIndex, int VertexOffset);
template<typename IndexType>
bool MinIntersectDist(const lcVector3& Start, const lcVector3& End, float& MinDist, lcVector3& Intersection);
bool MinIntersectDist(const lcVector3& Start, const lcVector3& End, float& MinDist, lcVector3& Intersection);
template<typename IndexType>
bool IntersectsPlanes(const lcVector4 Planes[6]);
bool IntersectsPlanes(const lcVector4 Planes[6]);
void UpdateBuffers()
{
mVertexBuffer.UpdateBuffer();
mIndexBuffer.UpdateBuffer();
}
lcMeshSection* mSections;
int mNumSections;
lcVertexBuffer mVertexBuffer;
lcIndexBuffer mIndexBuffer;
int mNumVertices;
int mNumTexturedVertices;
int mIndexType;
};
#endif // _LC_MESH_H_

95
common/lc_profile.cpp Normal file
View file

@ -0,0 +1,95 @@
#include "lc_global.h"
#include "lc_profile.h"
#include "image.h"
#include "project.h"
lcProfileEntry::lcProfileEntry(const char* Section, const char* Key, int DefaultValue)
{
mType = LC_PROFILE_ENTRY_INT;
mSection = Section;
mKey = Key;
mDefault.IntValue = DefaultValue;
}
lcProfileEntry::lcProfileEntry(const char* Section, const char* Key, unsigned int DefaultValue)
{
mType = LC_PROFILE_ENTRY_INT;
mSection = Section;
mKey = Key;
mDefault.IntValue = DefaultValue;
}
lcProfileEntry::lcProfileEntry(const char* Section, const char* Key, float DefaultValue)
{
mType = LC_PROFILE_ENTRY_FLOAT;
mSection = Section;
mKey = Key;
mDefault.FloatValue = DefaultValue;
}
lcProfileEntry::lcProfileEntry(const char* Section, const char* Key, const char* DefaultValue)
{
mType = LC_PROFILE_ENTRY_STRING;
mSection = Section;
mKey = Key;
mDefault.StringValue = DefaultValue;
}
lcProfileEntry::lcProfileEntry(const char* Section, const char* Key)
{
mType = LC_PROFILE_ENTRY_BUFFER;
mSection = Section;
mKey = Key;
mDefault.IntValue = 0;
}
lcProfileEntry gProfileEntries[LC_NUM_PROFILE_KEYS] =
{
lcProfileEntry("Settings", "Detail", LC_DET_BRICKEDGES), // LC_PROFILE_DETAIL
lcProfileEntry("Settings", "Snap", LC_DRAW_SNAP_A | LC_DRAW_SNAP_XYZ), // LC_PROFILE_SNAP
lcProfileEntry("Settings", "AngleSnap", 30), // LC_PROFILE_ANGLE_SNAP
lcProfileEntry("Settings", "LineWidth", 1.0f), // LC_PROFILE_LINE_WIDTH
lcProfileEntry("Settings", "GridSize", 20), // LC_PROFILE_GRID_SIZE
lcProfileEntry("Settings", "AASamples", 1), // LC_PROFILE_ANTIALIASING_SAMPLES
lcProfileEntry("Settings", "CheckUpdates", 1), // LC_PROFILE_CHECK_UPDATES
lcProfileEntry("Settings", "ProjectsPath", ""), // LC_PROFILE_PROJECTS_PATH
lcProfileEntry("Settings", "PartsLibrary", ""), // LC_PROFILE_PARTS_LIBRARY
lcProfileEntry("Settings", "Shortcuts"), // LC_PROFILE_SHORTCUTS
lcProfileEntry("Settings", "Categories"), // LC_PROFILE_CATEGORIES
lcProfileEntry("Settings", "RecentFile1", ""), // LC_PROFILE_RECENT_FILE1
lcProfileEntry("Settings", "RecentFile2", ""), // LC_PROFILE_RECENT_FILE2
lcProfileEntry("Settings", "RecentFile3", ""), // LC_PROFILE_RECENT_FILE3
lcProfileEntry("Settings", "RecentFile4", ""), // LC_PROFILE_RECENT_FILE4
lcProfileEntry("Settings", "AutosaveInterval", 10), // LC_PROFILE_AUTOSAVE_INTERVAL
lcProfileEntry("Settings", "MouseSensitivity", 11), // LC_PROFILE_MOUSE_SENSITIVITY
lcProfileEntry("Settings", "ImageWidth", 1280), // LC_PROFILE_IMAGE_WIDTH
lcProfileEntry("Settings", "ImageHeight", 720), // LC_PROFILE_IMAGE_HEIGHT
lcProfileEntry("Settings", "ImageOptions", LC_IMAGE_PNG | LC_IMAGE_TRANSPARENT), // LC_PROFILE_IMAGE_OPTIONS
lcProfileEntry("Settings", "PrintRows", 1), // LC_PROFILE_PRINT_ROWS
lcProfileEntry("Settings", "PrintColumns", 1), // LC_PROFILE_PRINT_COLUMNS
lcProfileEntry("Defaults", "Author", ""), // LC_PROFILE_DEFAULT_AUTHOR_NAME
lcProfileEntry("Defaults", "Scene", 0), // LC_PROFILE_DEFAULT_SCENE
lcProfileEntry("Defaults", "FloorColor", LC_RGB(0, 191, 0)), // LC_PROFILE_DEFAULT_FLOOR_COLOR
lcProfileEntry("Defaults", "FloorTexture", ""), // LC_PROFILE_DEFAULT_FLOOR_TEXTURE
lcProfileEntry("Defaults", "FogDensity", 0.1f), // LC_PROFILE_DEFAULT_FOG_DENSITY
lcProfileEntry("Defaults", "FogColor", LC_RGB(255, 255, 255)), // LC_PROFILE_DEFAULT_FOG_COLOR
lcProfileEntry("Defaults", "AmbientColor", LC_RGB(75, 75, 75)), // LC_PROFILE_DEFAULT_AMBIENT_COLOR
lcProfileEntry("Defaults", "BackgroundColor", LC_RGB(255, 255, 255)), // LC_PROFILE_DEFAULT_BACKGROUND_COLOR
lcProfileEntry("Defaults", "GradientColor1", LC_RGB(0, 0, 191)), // LC_PROFILE_DEFAULT_GRADIENT_COLOR1
lcProfileEntry("Defaults", "GradientColor2", LC_RGB(255, 255, 255)), // LC_PROFILE_DEFAULT_GRADIENT_COLOR2
lcProfileEntry("Defaults", "BackgroundTeture", ""), // LC_PROFILE_DEFAULT_BACKGROUND_TEXTURE
lcProfileEntry("HTML", "Options", LC_HTML_SINGLEPAGE), // LC_PROFILE_HTML_OPTIONS
lcProfileEntry("HTML", "ImageOptions", LC_IMAGE_PNG | LC_IMAGE_TRANSPARENT), // LC_PROFILE_HTML_IMAGE_OPTIONS
lcProfileEntry("HTML", "ImageWidth", 640), // LC_PROFILE_HTML_IMAGE_WIDTH
lcProfileEntry("HTML", "ImageHeight", 480), // LC_PROFILE_HTML_IMAGE_HEIGHT
lcProfileEntry("HTML", "PartsColor", 16), // LC_PROFILE_HTML_PARTS_COLOR
lcProfileEntry("HTML", "PartsWidth", 128), // LC_PROFILE_HTML_PARTS_WIDTH
lcProfileEntry("HTML", "PartsHeight", 128), // LC_PROFILE_HTML_PARTS_HEIGHT
lcProfileEntry("POVRay", "Path", ""), // LC_PROFILE_POVRAY_PATH
lcProfileEntry("POVRay", "LGEOPath", ""), // LC_PROFILE_POVRAY_LGEO_PATH
lcProfileEntry("POVRay", "Render", 1), // LC_PROFILE_POVRAY_RENDER
};

103
common/lc_profile.h Normal file
View file

@ -0,0 +1,103 @@
#ifndef LC_PROFILE_H
#define LC_PROFILE_H
enum LC_PROFILE_KEY
{
// Settings.
LC_PROFILE_DETAIL,
LC_PROFILE_SNAP,
LC_PROFILE_ANGLE_SNAP,
LC_PROFILE_LINE_WIDTH,
LC_PROFILE_GRID_SIZE,
LC_PROFILE_ANTIALIASING_SAMPLES,
LC_PROFILE_CHECK_UPDATES,
LC_PROFILE_PROJECTS_PATH,
LC_PROFILE_PARTS_LIBRARY,
LC_PROFILE_SHORTCUTS,
LC_PROFILE_CATEGORIES,
LC_PROFILE_RECENT_FILE1,
LC_PROFILE_RECENT_FILE2,
LC_PROFILE_RECENT_FILE3,
LC_PROFILE_RECENT_FILE4,
LC_PROFILE_AUTOSAVE_INTERVAL,
LC_PROFILE_MOUSE_SENSITIVITY,
LC_PROFILE_IMAGE_WIDTH,
LC_PROFILE_IMAGE_HEIGHT,
LC_PROFILE_IMAGE_OPTIONS,
LC_PROFILE_PRINT_ROWS,
LC_PROFILE_PRINT_COLUMNS,
// Defaults for new projects.
LC_PROFILE_DEFAULT_AUTHOR_NAME,
LC_PROFILE_DEFAULT_SCENE,
LC_PROFILE_DEFAULT_FLOOR_COLOR,
LC_PROFILE_DEFAULT_FLOOR_TEXTURE,
LC_PROFILE_DEFAULT_FOG_DENSITY,
LC_PROFILE_DEFAULT_FOG_COLOR,
LC_PROFILE_DEFAULT_AMBIENT_COLOR,
LC_PROFILE_DEFAULT_BACKGROUND_COLOR,
LC_PROFILE_DEFAULT_GRADIENT_COLOR1,
LC_PROFILE_DEFAULT_GRADIENT_COLOR2,
LC_PROFILE_DEFAULT_BACKGROUND_TEXTURE,
// Exporters.
LC_PROFILE_HTML_OPTIONS,
LC_PROFILE_HTML_IMAGE_OPTIONS,
LC_PROFILE_HTML_IMAGE_WIDTH,
LC_PROFILE_HTML_IMAGE_HEIGHT,
LC_PROFILE_HTML_PARTS_COLOR,
LC_PROFILE_HTML_PARTS_WIDTH,
LC_PROFILE_HTML_PARTS_HEIGHT,
LC_PROFILE_POVRAY_PATH,
LC_PROFILE_POVRAY_LGEO_PATH,
LC_PROFILE_POVRAY_RENDER,
LC_NUM_PROFILE_KEYS
};
enum LC_PROFILE_ENTRY_TYPE
{
LC_PROFILE_ENTRY_INT,
LC_PROFILE_ENTRY_FLOAT,
LC_PROFILE_ENTRY_STRING,
LC_PROFILE_ENTRY_BUFFER
};
class lcProfileEntry
{
public:
lcProfileEntry(const char* Section, const char* Key, int DefaultValue);
lcProfileEntry(const char* Section, const char* Key, unsigned int DefaultValue);
lcProfileEntry(const char* Section, const char* Key, float DefaultValue);
lcProfileEntry(const char* Section, const char* Key, const char* DefaultValue);
lcProfileEntry(const char* Section, const char* Key);
LC_PROFILE_ENTRY_TYPE mType;
const char* mSection;
const char* mKey;
union
{
int IntValue;
float FloatValue;
const char* StringValue;
} mDefault;
};
extern lcProfileEntry gProfileEntries[LC_NUM_PROFILE_KEYS];
void lcRemoveProfileKey(LC_PROFILE_KEY Key);
int lcGetProfileInt(LC_PROFILE_KEY Key);
float lcGetProfileFloat(LC_PROFILE_KEY Key);
const char* lcGetProfileString(LC_PROFILE_KEY Key);
void lcGetProfileBuffer(LC_PROFILE_KEY Key, lcMemFile& Buffer);
void lcSetProfileInt(LC_PROFILE_KEY Key, int Value);
void lcSetProfileFloat(LC_PROFILE_KEY Key, float Value);
void lcSetProfileString(LC_PROFILE_KEY Key, const char* Value);
void lcSetProfileBuffer(LC_PROFILE_KEY Key, const lcMemFile& Buffer);
#endif // LC_PROFILE_H

110
common/lc_shortcuts.cpp Normal file
View file

@ -0,0 +1,110 @@
#include "lc_global.h"
#include "lc_shortcuts.h"
#include "lc_profile.h"
#include "lc_file.h"
lcKeyboardShortcuts gKeyboardShortcuts;
void lcLoadDefaultKeyboardShortcuts()
{
lcMemFile File;
lcGetProfileBuffer(LC_PROFILE_SHORTCUTS, File);
if (!File.GetLength() || !lcLoadKeyboardShortcuts(File, gKeyboardShortcuts))
lcResetKeyboardShortcuts(gKeyboardShortcuts);
}
void lcSaveDefaultKeyboardShortcuts()
{
lcMemFile File;
lcSaveKeyboardShortcuts(File, gKeyboardShortcuts);
lcSetProfileBuffer(LC_PROFILE_SHORTCUTS, File);
}
void lcResetDefaultKeyboardShortcuts()
{
lcResetKeyboardShortcuts(gKeyboardShortcuts);
lcRemoveProfileKey(LC_PROFILE_SHORTCUTS);
}
void lcResetKeyboardShortcuts(lcKeyboardShortcuts& Shortcuts)
{
for (int CommandIdx = 0; CommandIdx < LC_NUM_COMMANDS; CommandIdx++)
strcpy(Shortcuts.Shortcuts[CommandIdx], gCommands[CommandIdx].DefaultShortcut);
}
bool lcSaveKeyboardShortcuts(const char* FileName, const lcKeyboardShortcuts& Shortcuts)
{
lcDiskFile File;
if (!File.Open(FileName, "wt"))
return false;
return lcSaveKeyboardShortcuts(File, Shortcuts);
}
bool lcSaveKeyboardShortcuts(lcFile& File, const lcKeyboardShortcuts& Shortcuts)
{
char Line[1024];
for (int CommandIdx = 0; CommandIdx < LC_NUM_COMMANDS; CommandIdx++)
{
if (!Shortcuts.Shortcuts[CommandIdx][0])
continue;
sprintf(Line, "%s=%s\n", gCommands[CommandIdx].ID, Shortcuts.Shortcuts[CommandIdx]);
File.WriteLine(Line);
}
return true;
}
bool lcLoadKeyboardShortcuts(const char* FileName, lcKeyboardShortcuts& Shortcuts)
{
lcDiskFile File;
if (!File.Open(FileName, "rt"))
return false;
return lcLoadKeyboardShortcuts(File, Shortcuts);
}
bool lcLoadKeyboardShortcuts(lcFile& File, lcKeyboardShortcuts& Shortcuts)
{
for (int CommandIdx = 0; CommandIdx < LC_NUM_COMMANDS; CommandIdx++)
Shortcuts.Shortcuts[CommandIdx][0] = 0;
char Line[1024];
while (File.ReadLine(Line, sizeof(Line)))
{
char* Key = strchr(Line, '=');
if (!Key)
continue;
*Key = 0;
Key++;
int CommandIdx;
for (CommandIdx = 0; CommandIdx < LC_NUM_COMMANDS; CommandIdx++)
if (!strcmp(gCommands[CommandIdx].ID, Line))
break;
if (CommandIdx == LC_NUM_COMMANDS)
continue;
char* NewLine = strchr(Key, '\n');
if (NewLine)
*NewLine = 0;
strncpy(Shortcuts.Shortcuts[CommandIdx], Key, LC_SHORTCUT_LENGTH);
}
return true;
}

25
common/lc_shortcuts.h Normal file
View file

@ -0,0 +1,25 @@
#ifndef _LC_SHORTCUTS_H_
#define _LC_SHORTCUTS_H_
#include "lc_commands.h"
#define LC_SHORTCUT_LENGTH 32
struct lcKeyboardShortcuts
{
char Shortcuts[LC_NUM_COMMANDS][LC_SHORTCUT_LENGTH];
};
extern lcKeyboardShortcuts gKeyboardShortcuts;
void lcLoadDefaultKeyboardShortcuts();
void lcSaveDefaultKeyboardShortcuts();
void lcResetDefaultKeyboardShortcuts();
void lcResetKeyboardShortcuts(lcKeyboardShortcuts& Shortcuts);
bool lcSaveKeyboardShortcuts(const char* FileName, const lcKeyboardShortcuts& Shortcuts);
bool lcSaveKeyboardShortcuts(lcFile& File, const lcKeyboardShortcuts& Shortcuts);
bool lcLoadKeyboardShortcuts(const char* FileName, lcKeyboardShortcuts& Shortcuts);
bool lcLoadKeyboardShortcuts(lcFile& File, lcKeyboardShortcuts& Shortcuts);
#endif // _LC_SHORTCUTS_H_

View file

@ -1,97 +1,102 @@
#include "lc_global.h"
#include "lc_texture.h"
#include "lc_file.h"
#include "lc_application.h"
#include "lc_library.h"
#include "image.h"
lcTexture::lcTexture()
{
mTexture = 0;
mRefCount = 0;
}
lcTexture::~lcTexture()
{
Unload();
}
bool lcTexture::Load()
{
return lcGetPiecesLibrary()->LoadTexture(this);
}
bool lcTexture::Load(const char* FileName, int Flags)
{
lcDiskFile File;
if (!File.Open(FileName, "rb"))
return false;
return Load(File, Flags);
}
bool lcTexture::Load(lcFile& File, int Flags)
{
Image image;
if (!image.FileLoad(File))
return false;
image.ResizePow2();
mWidth = image.Width();
mHeight = image.Height();
glGenTextures(1, &mTexture);
glBindTexture(GL_TEXTURE_2D, mTexture);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, (Flags & LC_TEXTURE_WRAPU) ? GL_REPEAT : GL_CLAMP);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, (Flags & LC_TEXTURE_WRAPV) ? GL_REPEAT : GL_CLAMP);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, (Flags & LC_TEXTURE_MIPMAPS) ? GL_LINEAR_MIPMAP_NEAREST : GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
int Format = image.Alpha() ? GL_RGBA : GL_RGB;
void* Data = image.GetData();
glTexImage2D(GL_TEXTURE_2D, 0, image.Alpha() ? GL_RGBA : GL_RGB, mWidth, mHeight, 0, Format, GL_UNSIGNED_BYTE, Data);
if (Flags & LC_TEXTURE_MIPMAPS)
{
int Width = mWidth;
int Height = mHeight;
int Components = (Format == GL_RGBA) ? 4 : 3;
for (int Level = 1; ((Width != 1) || (Height != 1)); Level++)
{
GLubyte *Out, *In;
int RowStride = Width * Components;
Width = lcMax(1, Width >> 1);
Height = lcMax(1, Height >> 1);
In = Out = (GLubyte*)Data;
for (int y = 0; y < Height; y++, In += RowStride)
for (int x = 0; x < Width; x++, Out += Components, In += 2 * Components)
for (int c = 0; c < Components; c++)
Out[c] = (In[c] + In[c + Components] + In[RowStride] + In[c + RowStride + Components]) / 4;
glTexImage2D(GL_TEXTURE_2D, Level, Components, Width, Height, 0, Format, GL_UNSIGNED_BYTE, Data);
}
}
glBindTexture(GL_TEXTURE_2D, 0);
return true;
}
void lcTexture::Unload()
{
if (mTexture)
glDeleteTextures(1, &mTexture);
mTexture = 0;
}
#include "lc_global.h"
#include "lc_texture.h"
#include "lc_file.h"
#include "lc_application.h"
#include "lc_library.h"
#include "image.h"
lcTexture::lcTexture()
{
mTexture = 0;
mRefCount = 0;
}
lcTexture::~lcTexture()
{
Unload();
}
bool lcTexture::Load()
{
return lcGetPiecesLibrary()->LoadTexture(this);
}
bool lcTexture::Load(const char* FileName, int Flags)
{
Image image;
if (!image.FileLoad(FileName))
return false;
return Load(image, Flags);
}
bool lcTexture::Load(lcMemFile& File, int Flags)
{
Image image;
if (!image.FileLoad(File))
return false;
return Load(image, Flags);
}
bool lcTexture::Load(Image& image, int Flags)
{
image.ResizePow2();
mWidth = image.mWidth;
mHeight = image.mHeight;
glGenTextures(1, &mTexture);
glBindTexture(GL_TEXTURE_2D, mTexture);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, (Flags & LC_TEXTURE_WRAPU) ? GL_REPEAT : GL_CLAMP);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, (Flags & LC_TEXTURE_WRAPV) ? GL_REPEAT : GL_CLAMP);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, (Flags & LC_TEXTURE_MIPMAPS) ? GL_LINEAR_MIPMAP_NEAREST : GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
int Format = image.mAlpha ? GL_RGBA : GL_RGB;
void* Data = image.mData;
glTexImage2D(GL_TEXTURE_2D, 0, image.mAlpha ? GL_RGBA : GL_RGB, mWidth, mHeight, 0, Format, GL_UNSIGNED_BYTE, Data);
if (Flags & LC_TEXTURE_MIPMAPS)
{
int Width = mWidth;
int Height = mHeight;
int Components = (Format == GL_RGBA) ? 4 : 3;
for (int Level = 1; ((Width != 1) || (Height != 1)); Level++)
{
GLubyte *Out, *In;
int RowStride = Width * Components;
Width = lcMax(1, Width >> 1);
Height = lcMax(1, Height >> 1);
In = Out = (GLubyte*)Data;
for (int y = 0; y < Height; y++, In += RowStride)
for (int x = 0; x < Width; x++, Out += Components, In += 2 * Components)
for (int c = 0; c < Components; c++)
Out[c] = (In[c] + In[c + Components] + In[RowStride] + In[c + RowStride + Components]) / 4;
glTexImage2D(GL_TEXTURE_2D, Level, Components, Width, Height, 0, Format, GL_UNSIGNED_BYTE, Data);
}
}
glBindTexture(GL_TEXTURE_2D, 0);
return true;
}
void lcTexture::Unload()
{
if (mTexture)
glDeleteTextures(1, &mTexture);
mTexture = 0;
}

View file

@ -1,53 +1,56 @@
#ifndef _LC_TEXTURE_H_
#define _LC_TEXTURE_H_
#include "opengl.h"
#define LC_TEXTURE_WRAPU 0x01
#define LC_TEXTURE_WRAPV 0x02
#define LC_TEXTURE_MIPMAPS 0x04
#define LC_TEXTURE_NAME_LEN 256
class lcTexture
{
public:
lcTexture();
~lcTexture();
bool Load(const char* FileName, int Flags = 0);
bool Load(lcFile& File, int Flags = 0);
void Unload();
int AddRef()
{
mRefCount++;
if (mRefCount == 1)
Load();
return mRefCount;
}
int Release()
{
mRefCount--;
if (!mRefCount)
Unload();
return mRefCount;
}
int mWidth;
int mHeight;
char mName[LC_TEXTURE_NAME_LEN];
GLuint mTexture;
protected:
bool Load();
int mRefCount;
};
#endif // _LC_TEXTURE_H_
#ifndef _LC_TEXTURE_H_
#define _LC_TEXTURE_H_
#include "opengl.h"
#define LC_TEXTURE_WRAPU 0x01
#define LC_TEXTURE_WRAPV 0x02
#define LC_TEXTURE_MIPMAPS 0x04
#define LC_TEXTURE_NAME_LEN 256
class Image;
class lcTexture
{
public:
lcTexture();
~lcTexture();
bool Load(const char* FileName, int Flags = 0);
bool Load(lcMemFile& File, int Flags = 0);
bool Load(Image& image, int Flags);
void Unload();
int AddRef()
{
mRefCount++;
if (mRefCount == 1)
Load();
return mRefCount;
}
int Release()
{
mRefCount--;
if (!mRefCount)
Unload();
return mRefCount;
}
int mWidth;
int mHeight;
char mName[LC_TEXTURE_NAME_LEN];
GLuint mTexture;
protected:
bool Load();
int mRefCount;
};
#endif // _LC_TEXTURE_H_

File diff suppressed because it is too large Load diff

View file

@ -1,81 +1,85 @@
#ifndef _LC_ZIPFILE_H_
#define _LC_ZIPFILE_H_
#include "array.h"
class lcFile;
// Date/time info.
struct tm_unz
{
lcuint32 tm_sec; // seconds after the minute - [0,59]
lcuint32 tm_min; // minutes after the hour - [0,59]
lcuint32 tm_hour; // hours since midnight - [0,23]
lcuint32 tm_mday; // day of the month - [1,31]
lcuint32 tm_mon; // months since January - [0,11]
lcuint32 tm_year; // years - [1980..2044]
};
// Information about a file in the zipfile.
struct lcZipFileInfo
{
lcuint16 version; // version made by 2 bytes
lcuint16 version_needed; // version needed to extract 2 bytes
lcuint16 flag; // general purpose bit flag 2 bytes
lcuint16 compression_method; // compression method 2 bytes
lcuint32 dosDate; // last mod file date in Dos fmt 4 bytes
lcuint32 crc; // crc-32 4 bytes
lcuint64 compressed_size; // compressed size 8 bytes
lcuint64 uncompressed_size; // uncompressed size 8 bytes
lcuint16 size_filename; // filename length 2 bytes
lcuint16 size_file_extra; // extra field length 2 bytes
lcuint16 size_file_comment; // file comment length 2 bytes
lcuint16 disk_num_start; // disk number start 2 bytes
lcuint16 internal_fa; // internal file attributes 2 bytes
lcuint32 external_fa; // external file attributes 4 bytes
lcuint64 offset_curfile; // relative offset of local header 8 bytes
char file_name[256];
tm_unz tmu_date;
lcMemFile* write_buffer;
bool deleted;
};
class lcZipFile
{
public:
lcZipFile();
~lcZipFile();
bool OpenRead(const char* FilePath);
bool OpenWrite(const char* FilePath, bool Append);
bool ExtractFile(int FileIndex, lcMemFile& File, lcuint32 MaxLength = 0xffffffff);
bool ExtractFile(const char* FileName, lcMemFile& File, lcuint32 MaxLength = 0xffffffff);
bool AddFile(const char* FileName, lcMemFile& File);
bool DeleteFile(const char* FileName);
ObjArray<lcZipFileInfo> mFiles;
protected:
bool Open();
void Flush();
bool ReadCentralDir();
lcuint64 SearchCentralDir();
lcuint64 SearchCentralDir64();
bool CheckFileCoherencyHeader(int FileIndex, lcuint32* SizeVar, lcuint64* OffsetLocalExtraField, lcuint32* SizeLocalExtraField);
lcDiskFile* mFile;
bool mModified;
bool mZip64;
lcuint64 mNumEntries;
lcuint64 mCentralDirSize;
lcuint64 mCentralDirOffset;
lcuint64 mBytesBeforeZipFile;
lcuint64 mCentralPos;
};
#endif // _LC_ZIPFILE_H_
#ifndef _LC_ZIPFILE_H_
#define _LC_ZIPFILE_H_
#include "array.h"
#ifdef DeleteFile
#undef DeleteFile
#endif
class lcFile;
// Date/time info.
struct tm_unz
{
lcuint32 tm_sec; // seconds after the minute - [0,59]
lcuint32 tm_min; // minutes after the hour - [0,59]
lcuint32 tm_hour; // hours since midnight - [0,23]
lcuint32 tm_mday; // day of the month - [1,31]
lcuint32 tm_mon; // months since January - [0,11]
lcuint32 tm_year; // years - [1980..2044]
};
// Information about a file in the zipfile.
struct lcZipFileInfo
{
lcuint16 version; // version made by 2 bytes
lcuint16 version_needed; // version needed to extract 2 bytes
lcuint16 flag; // general purpose bit flag 2 bytes
lcuint16 compression_method; // compression method 2 bytes
lcuint32 dosDate; // last mod file date in Dos fmt 4 bytes
lcuint32 crc; // crc-32 4 bytes
lcuint64 compressed_size; // compressed size 8 bytes
lcuint64 uncompressed_size; // uncompressed size 8 bytes
lcuint16 size_filename; // filename length 2 bytes
lcuint16 size_file_extra; // extra field length 2 bytes
lcuint16 size_file_comment; // file comment length 2 bytes
lcuint16 disk_num_start; // disk number start 2 bytes
lcuint16 internal_fa; // internal file attributes 2 bytes
lcuint32 external_fa; // external file attributes 4 bytes
lcuint64 offset_curfile; // relative offset of local header 8 bytes
char file_name[256];
tm_unz tmu_date;
lcMemFile* write_buffer;
bool deleted;
};
class lcZipFile
{
public:
lcZipFile();
~lcZipFile();
bool OpenRead(const char* FilePath);
bool OpenWrite(const char* FilePath, bool Append);
bool ExtractFile(int FileIndex, lcMemFile& File, lcuint32 MaxLength = 0xffffffff);
bool ExtractFile(const char* FileName, lcMemFile& File, lcuint32 MaxLength = 0xffffffff);
bool AddFile(const char* FileName, lcMemFile& File);
bool DeleteFile(const char* FileName);
ObjArray<lcZipFileInfo> mFiles;
protected:
bool Open();
void Flush();
bool ReadCentralDir();
lcuint64 SearchCentralDir();
lcuint64 SearchCentralDir64();
bool CheckFileCoherencyHeader(int FileIndex, lcuint32* SizeVar, lcuint64* OffsetLocalExtraField, lcuint32* SizeLocalExtraField);
lcDiskFile* mFile;
bool mModified;
bool mZip64;
lcuint64 mNumEntries;
lcuint64 mCentralDirSize;
lcuint64 mCentralDirOffset;
lcuint64 mBytesBeforeZipFile;
lcuint64 mCentralPos;
};
#endif // _LC_ZIPFILE_H_

View file

@ -6,7 +6,6 @@
#include <stdio.h>
#include <math.h>
#include "light.h"
#include "globals.h"
static LC_OBJECT_KEY_INFO light_key_info[LC_LK_COUNT] =
{
@ -192,7 +191,7 @@ void Light::Select(bool bSelecting, bool bFocus, bool bMultiple)
m_nState &= ~(LC_LIGHT_FOCUSED);
else
m_nState &= ~(LC_LIGHT_SELECTED|LC_LIGHT_FOCUSED);
}
}
}
void Light::SelectTarget(bool bSelecting, bool bFocus, bool bMultiple)
@ -219,7 +218,7 @@ void Light::SelectTarget(bool bSelecting, bool bFocus, bool bMultiple)
m_nState &= ~(LC_LIGHT_TARGET_FOCUSED);
else
m_nState &= ~(LC_LIGHT_TARGET_SELECTED|LC_LIGHT_TARGET_FOCUSED);
}
}
}
void Light::MinIntersectDist(lcClickLine* ClickLine)

View file

@ -1,102 +1,60 @@
//
// Main LeoCAD window
//
#include "lc_global.h"
#include <stdio.h>
#include "mainwnd.h"
#include "system.h"
#include "lc_profile.h"
#include "preview.h"
MainWnd::MainWnd ()
: BaseWnd (NULL, LC_MAINWND_NUM_COMMANDS)
{
char entry[8];
int i;
lcMainWindow* gMainWindow;
for (i = 0; i < LC_MRU_MAX; i++)
lcMainWindow::lcMainWindow()
{
sprintf (entry, "File%d", i+1);
m_strMRU[i] = Sys_ProfileLoadString ("RecentFiles", entry, "");
}
mColorIndex = 0;
mPreviewWidget = NULL;
for (int FileIdx = 0; FileIdx < LC_MAX_RECENT_FILES; FileIdx++)
strcpy(mRecentFiles[FileIdx], lcGetProfileString((LC_PROFILE_KEY)(LC_PROFILE_RECENT_FILE1 + FileIdx)));
gMainWindow = this;
}
MainWnd::~MainWnd ()
lcMainWindow::~lcMainWindow()
{
char entry[8];
int i;
for (int FileIdx = 0; FileIdx < LC_MAX_RECENT_FILES; FileIdx++)
lcSetProfileString((LC_PROFILE_KEY)(LC_PROFILE_RECENT_FILE1 + FileIdx), mRecentFiles[FileIdx]);
for (i = 0; i < LC_MRU_MAX; i++)
{
sprintf (entry, "File%d", i+1);
Sys_ProfileSaveString ("RecentFiles", entry, m_strMRU[i]);
}
gMainWindow = NULL;
}
// =============================================================================
// recently used files
void MainWnd::UpdateMRU ()
{
#ifdef LC_WINDOWS
// FIXME !!
void SystemUpdateRecentMenu(char names[4][MAX_PATH]);
char names[4][MAX_PATH];
for (int i = 0; i < LC_MRU_MAX; i++)
strcpy (names[i], m_strMRU[i]);
SystemUpdateRecentMenu(names);
#else
for (int i = 0; i < LC_MRU_MAX; i++)
void lcMainWindow::SetColorIndex(int ColorIndex)
{
if (m_strMRU[i].IsEmpty ())
{
if (i == 0)
{
SetMenuItemText (LC_MAINWND_RECENT1, "Recent Files");
EnableMenuItem (LC_MAINWND_RECENT1, false);
}
else
ShowMenuItem (LC_MAINWND_RECENT1+i, false);
}
else
{
char text[LC_MAXPATH+8];
sprintf (text, "&%d- %s", i+1, (char*)m_strMRU[i]);
mColorIndex = ColorIndex;
ShowMenuItem (LC_MAINWND_RECENT1+i, true);
EnableMenuItem (LC_MAINWND_RECENT1+i, true);
SetMenuItemText (LC_MAINWND_RECENT1+i, text);
}
}
#endif
if (mPreviewWidget)
mPreviewWidget->Redraw();
}
void MainWnd::AddToMRU(const char* Filename)
void lcMainWindow::AddRecentFile(const char* FileName)
{
// Make a copy of the string in case we're loading a file from the MRU menu.
String str = Filename;
int i;
int FileIdx;
// Search for Filename in the MRU list.
for (i = 0; i < (LC_MRU_MAX - 1); i++)
if (m_strMRU[i] == Filename)
for (FileIdx = 0; FileIdx < LC_MAX_RECENT_FILES; FileIdx++)
if (!strcmp(mRecentFiles[FileIdx], FileName))
break;
// Move MRU strings before this one down.
for (; i > 0; i--)
m_strMRU[i] = m_strMRU[i-1];
for (FileIdx = lcMin(FileIdx, LC_MAX_RECENT_FILES - 1); FileIdx > 0; FileIdx--)
strcpy(mRecentFiles[FileIdx], mRecentFiles[FileIdx - 1]);
m_strMRU[0] = str;
strcpy(mRecentFiles[0], FileName);
UpdateMRU();
UpdateRecentFiles();
}
void MainWnd::RemoveFromMRU(int index)
void lcMainWindow::RemoveRecentFile(int FileIndex)
{
for (int i = index; i < (LC_MRU_MAX - 1); i++)
m_strMRU[i] = m_strMRU[i+1];
m_strMRU[LC_MRU_MAX - 1].Empty ();
for (int FileIdx = FileIndex; FileIdx < LC_MAX_RECENT_FILES - 1; FileIdx++)
strcpy(mRecentFiles[FileIdx], mRecentFiles[FileIdx + 1]);
UpdateMRU ();
mRecentFiles[LC_MAX_RECENT_FILES - 1][0] = 0;
UpdateRecentFiles();
}

View file

@ -1,34 +1,60 @@
#ifndef _MAINWND_H_
#define _MAINWND_H_
#include "str.h"
#include "basewnd.h"
#include "array.h"
#define LC_MRU_MAX 4
class Object;
class Camera;
class PiecePreview;
typedef enum
{
LC_MAINWND_RECENT1,
LC_MAINWND_RECENT2,
LC_MAINWND_RECENT3,
LC_MAINWND_RECENT4,
LC_MAINWND_NUM_COMMANDS
} LC_MAINWND_COMMANDS;
#define LC_MAX_RECENT_FILES 4
class MainWnd : public BaseWnd
class lcMainWindow : public lcBaseWindow
{
public:
MainWnd ();
virtual ~MainWnd ();
lcMainWindow();
~lcMainWindow();
void UpdateMRU ();
void AddToMRU (const char *filename);
void RemoveFromMRU (int index);
const char* GetMRU (int index) const
{ return m_strMRU[index]; }
void SetColorIndex(int ColorIndex);
void Close();
protected:
String m_strMRU[LC_MRU_MAX];
void AddRecentFile(const char* FileName);
void RemoveRecentFile(int FileIndex);
void SplitHorizontal();
void SplitVertical();
void RemoveView();
void ResetViews();
void TogglePrintPreview();
void ToggleFullScreen();
void UpdateFocusObject(Object* Focus);
void UpdateSelectedObjects(int Flags, int SelectedCount, Object* Focus);
void UpdateAction(int NewAction);
void UpdatePaste(bool Enabled);
void UpdateTime(bool Animation, int CurrentTime, int TotalTime);
void UpdateAnimation(bool Animation, bool AddKeys);
void UpdateLockSnap(lcuint32 Snap);
void UpdateSnap();
void UpdateUndoRedo(const char* UndoText, const char* RedoText);
void UpdateTransformType(int NewType);
void UpdateCurrentCamera(int CameraIndex);
void UpdateCameraMenu(const PtrArray<Camera>& Cameras, Camera* CurrentCamera);
void UpdateCategories();
void UpdateTitle(const char* Title, bool Modified);
void UpdateModified(bool Modified);
void UpdateRecentFiles();
void UpdateShortcuts();
lcVector3 GetTransformAmount();
char mRecentFiles[LC_MAX_RECENT_FILES][LC_MAXPATH];
PiecePreview* mPreviewWidget;
int mColorIndex;
};
extern class lcMainWindow* gMainWindow;
#endif // _MAINWND_H_

View file

@ -1,33 +0,0 @@
//
// LeoCAD messaging system
//
#include "lc_global.h"
#include "message.h"
Messenger::Messenger ()
{
m_nRef = 0;
}
Messenger::~Messenger ()
{
for (int i = 0; i < m_Listeners.GetSize (); i++)
delete m_Listeners[i];
}
void Messenger::Dispatch (int message, void *data)
{
for (int i = 0; i < m_Listeners.GetSize (); i++)
m_Listeners[i]->func (message, data, m_Listeners[i]->user);
}
void Messenger::Listen (LC_MSG_CALLBACK func, void *user)
{
LC_MSG_STRUCT *s = new LC_MSG_STRUCT;
s->func = func;
s->user = user;
m_Listeners.Add (s);
}

View file

@ -1,40 +0,0 @@
#ifndef _MESSAGE_H_
#define _MESSAGE_H_
#include "array.h"
typedef void (*LC_MSG_CALLBACK) (int message, void *data, void *user);
typedef enum
{
LC_MSG_FOCUS_CHANGED,
// LC_MSG_SELECTION_CHANGED,
LC_MSG_COUNT
} LC_MSG_TYPES;
typedef struct
{
LC_MSG_CALLBACK func;
void *user;
} LC_MSG_STRUCT;
class Messenger
{
public:
Messenger ();
~Messenger ();
void AddRef ()
{ m_nRef++; };
void DecRef ()
{ m_nRef--; if (m_nRef == 0) delete this; };
void Dispatch (int message, void *data);
void Listen (LC_MSG_CALLBACK func, void *user);
protected:
int m_nRef;
PtrArray<LC_MSG_STRUCT> m_Listeners;
};
#endif // _MESSAGE_H_

View file

@ -1,7 +1,3 @@
//
// Minifig Wizard base class, calculates position/rotation of all pieces.
//
#include "lc_global.h"
#include "lc_colors.h"
#include "lc_math.h"
@ -12,7 +8,6 @@
#include "minifig.h"
#include "opengl.h"
#include "pieceinf.h"
#include "globals.h"
#include "project.h"
#include "system.h"
#include "lc_library.h"
@ -856,8 +851,7 @@ static int lcGetMinifigSettings(lcMemFile& File)
// =============================================================================
// MinifigWizard class
MinifigWizard::MinifigWizard(GLWindow *share)
: GLWindow (share)
MinifigWizard::MinifigWizard(lcMinifig* Minifig)
{
char Filename[LC_MAXPATH];
strcpy(Filename, lcGetPiecesLibrary()->mLibraryPath);
@ -875,70 +869,34 @@ MinifigWizard::MinifigWizard(GLWindow *share)
ParseSettings(MemSettings);
}
mMinifig = Minifig;
m_RotateX = 75.0f;
m_RotateZ = 180.0f;
m_Distance = 10.0f;
m_AutoZoom = true;
m_Tracking = LC_TRACK_NONE;
m_MinifigCount = 0;
m_MinifigNames = NULL;
m_MinifigTemplates = NULL;
memset(m_Info, 0, sizeof(m_Info));
int Version = Sys_ProfileLoadInt("MinifigWizard", "Version", 1);
if (Version == 1)
{
char *ptr, buf[32];
m_MinifigCount = Sys_ProfileLoadInt ("MinifigWizard", "Count", 0);
m_MinifigNames = (char**)realloc(m_MinifigNames, sizeof(char**) * (m_MinifigCount+1));
m_MinifigTemplates = (char**)realloc(m_MinifigTemplates, sizeof(char**) * (m_MinifigCount+1));
for (int i = 0; i < m_MinifigCount; i++)
{
sprintf (buf, "Minifig%.2dName", i);
ptr = Sys_ProfileLoadString ("MinifigWizard", buf, buf);
m_MinifigNames[i] = (char*)malloc (strlen (ptr) + 1);
strcpy (m_MinifigNames[i], ptr);
m_MinifigTemplates[i] = (char*)malloc (768);
sprintf (buf, "Minifig%.2dColors", i);
ptr = Sys_ProfileLoadString ("MinifigWizard", buf, "");
if (ptr[strlen (ptr) - 1] != ' ')
strcat (ptr, " ");
strcpy (m_MinifigTemplates[i], ptr);
sprintf (buf, "Minifig%.2dPieces", i);
ptr = Sys_ProfileLoadString ("MinifigWizard", buf, "");
if (ptr[strlen (ptr) - 1] != ' ')
strcat (ptr, " ");
strcat (m_MinifigTemplates[i], ptr);
sprintf (buf, "Minifig%.2dAngles", i);
ptr = Sys_ProfileLoadString ("MinifigWizard", buf, "");
strcat (m_MinifigTemplates[i], ptr);
}
}
else
Sys_MessageBox ("Unknown Minifig Preferences.");
}
void MinifigWizard::OnInitialUpdate()
{
MakeCurrent();
memset(mMinifig, 0, sizeof(lcMinifig));
const int ColorCodes[LC_MFW_NUMITEMS] = { 4, 7, 14, 7, 1, 0, 7, 4, 4, 14, 14, 7, 7, 0, 0, 7, 7 };
const char* Pieces[LC_MFW_NUMITEMS] = { "3624", "None", "3626BP01", "None", "973", "3815", "None", "3819", "3818", "3820", "3820", "None", "None", "3817", "3816", "None", "None" };
for (int i = 0; i < LC_MFW_NUMITEMS; i++)
{
m_Colors[i] = lcGetColorIndex(ColorCodes[i]);
m_Angles[i] = 0;
mMinifig->Colors[i] = lcGetColorIndex(ColorCodes[i]);
m_Info[i] = lcGetPiecesLibrary()->FindPiece(Pieces[i], false);
if (m_Info[i] != NULL)
m_Info[i]->AddRef();
PieceInfo* Info = lcGetPiecesLibrary()->FindPiece(Pieces[i], false);
if (Info)
{
mMinifig->Parts[i] = Info;
Info->AddRef();
}
}
Calculate();
@ -946,51 +904,9 @@ void MinifigWizard::OnInitialUpdate()
MinifigWizard::~MinifigWizard ()
{
char *ptr, buf[32];
int i, j;
Sys_ProfileSaveInt ("MinifigWizard", "Version", 1);
Sys_ProfileSaveInt ("MinifigWizard", "Count", m_MinifigCount);
for (i = 0; i < m_MinifigCount; i++)
{
char *value;
ptr = m_MinifigTemplates[i];
sprintf (buf, "Minifig%.2dName", i);
Sys_ProfileSaveString ("MinifigWizard", buf, m_MinifigNames[i]);
value = ptr;
for (j = 0; j < LC_MFW_NUMITEMS; j++)
ptr = strchr (ptr, ' ') + 1;
*(--ptr) = '\0';
sprintf (buf, "Minifig%.2dColors", i);
Sys_ProfileSaveString ("MinifigWizard", buf, value);
ptr++;
value = ptr;
for (j = 0; j < LC_MFW_NUMITEMS; j++)
ptr = strchr (ptr, ' ') + 1;
*(--ptr) = '\0';
sprintf (buf, "Minifig%.2dPieces", i);
Sys_ProfileSaveString ("MinifigWizard", buf, value);
ptr++;
sprintf (buf, "Minifig%.2dAngles", i);
Sys_ProfileSaveString ("MinifigWizard", buf, ptr);
free (m_MinifigNames[i]);
free (m_MinifigTemplates[i]);
}
free (m_MinifigNames);
free (m_MinifigTemplates);
for (i = 0; i < LC_MFW_NUMITEMS; i++)
if (m_Info[i])
m_Info[i]->Release();
for (int i = 0; i < LC_MFW_NUMITEMS; i++)
if (mMinifig->Parts[i])
mMinifig->Parts[i]->Release();
}
void MinifigWizard::ParseSettings(lcFile& Settings)
@ -1126,14 +1042,14 @@ void MinifigWizard::ParseSettings(lcFile& Settings)
void MinifigWizard::OnDraw()
{
float Aspect = (float)m_nWidth/(float)m_nHeight;
glViewport(0, 0, m_nWidth, m_nHeight);
float Aspect = (float)mWidth/(float)mHeight;
glViewport(0, 0, mWidth, mHeight);
float Box[6] = { 10000, 10000, 10000, -10000, -10000, -10000 };
for (int InfoIdx = 0; InfoIdx < LC_MFW_NUMITEMS; InfoIdx++)
{
PieceInfo* Info = m_Info[InfoIdx];
PieceInfo* Info = mMinifig->Parts[InfoIdx];
if (!Info)
continue;
@ -1152,7 +1068,7 @@ void MinifigWizard::OnDraw()
for (int PointIdx = 0; PointIdx < 8; PointIdx++)
{
lcVector3 Point = lcMul31(Points[PointIdx], m_Matrices[InfoIdx]);
lcVector3 Point = lcMul31(Points[PointIdx], mMinifig->Matrices[InfoIdx]);
if (Point[0] < Box[0]) Box[0] = Point[0];
if (Point[1] < Box[1]) Box[1] = Point[1];
@ -1220,28 +1136,28 @@ void MinifigWizard::OnDraw()
for (int PieceIdx = 0; PieceIdx < LC_MFW_NUMITEMS; PieceIdx++)
{
if (!m_Info[PieceIdx])
if (!mMinifig->Parts[PieceIdx])
continue;
glPushMatrix();
glMultMatrixf(m_Matrices[PieceIdx]);
m_Info[PieceIdx]->RenderPiece(m_Colors[PieceIdx]);
glMultMatrixf(mMinifig->Matrices[PieceIdx]);
mMinifig->Parts[PieceIdx]->RenderPiece(mMinifig->Colors[PieceIdx]);
glPopMatrix();
}
}
void MinifigWizard::OnLeftButtonDown(int x, int y, bool Control, bool Shift)
void MinifigWizard::OnLeftButtonDown()
{
if (m_Tracking == LC_TRACK_NONE)
{
m_DownX = x;
m_DownY = y;
m_DownX = mInputState.x;
m_DownY = mInputState.y;
m_Tracking = LC_TRACK_LEFT;
CaptureMouse();
}
}
void MinifigWizard::OnLeftButtonUp(int x, int y, bool Control, bool Shift)
void MinifigWizard::OnLeftButtonUp()
{
if (m_Tracking == LC_TRACK_LEFT)
{
@ -1250,24 +1166,24 @@ void MinifigWizard::OnLeftButtonUp(int x, int y, bool Control, bool Shift)
}
}
void MinifigWizard::OnLeftButtonDoubleClick(int x, int y, bool Control, bool Shift)
void MinifigWizard::OnLeftButtonDoubleClick()
{
m_AutoZoom = true;
Redraw();
}
void MinifigWizard::OnRightButtonDown(int x, int y, bool Control, bool Shift)
void MinifigWizard::OnRightButtonDown()
{
if (m_Tracking == LC_TRACK_NONE)
{
m_DownX = x;
m_DownY = y;
m_DownX = mInputState.x;
m_DownY = mInputState.y;
m_Tracking = LC_TRACK_RIGHT;
CaptureMouse();
}
}
void MinifigWizard::OnRightButtonUp(int x, int y, bool Control, bool Shift)
void MinifigWizard::OnRightButtonUp()
{
if (m_Tracking == LC_TRACK_RIGHT)
{
@ -1276,35 +1192,35 @@ void MinifigWizard::OnRightButtonUp(int x, int y, bool Control, bool Shift)
}
}
void MinifigWizard::OnMouseMove(int x, int y, bool Control, bool Shift)
void MinifigWizard::OnMouseMove()
{
if (m_Tracking == LC_TRACK_LEFT)
{
// Rotate.
m_RotateZ += x - m_DownX;
m_RotateX += y - m_DownY;
m_RotateZ += mInputState.x - m_DownX;
m_RotateX += mInputState.y - m_DownY;
if (m_RotateX > 179.5f)
m_RotateX = 179.5f;
else if (m_RotateX < 0.5f)
m_RotateX = 0.5f;
m_DownX = x;
m_DownY = y;
m_DownX = mInputState.x;
m_DownY = mInputState.y;
Redraw();
}
else if (m_Tracking == LC_TRACK_RIGHT)
{
// Zoom.
m_Distance += (float)(m_DownY - y) * 0.2f;
m_Distance += (float)(m_DownY - mInputState.y) * 0.2f;
m_AutoZoom = false;
if (m_Distance < 0.5f)
m_Distance = 0.5f;
m_DownX = x;
m_DownY = y;
m_DownX = mInputState.x;
m_DownY = mInputState.y;
Redraw();
}
@ -1315,46 +1231,50 @@ void MinifigWizard::Calculate()
float HeadOffset = 0.0f;
lcMatrix44 Root, Mat, Mat2;
bool DroidTorso = m_Info[LC_MFW_BODY] && !strcmp(m_Info[LC_MFW_BODY]->m_strName, "30375");
bool SkeletonTorso = m_Info[LC_MFW_BODY] && !strcmp(m_Info[LC_MFW_BODY]->m_strName, "6260");
PieceInfo** Parts = mMinifig->Parts;
float* Angles = mMinifig->Angles;
lcMatrix44* Matrices = mMinifig->Matrices;
if (m_Info[LC_MFW_BODY3])
bool DroidTorso = Parts[LC_MFW_BODY] && !strcmp(Parts[LC_MFW_BODY]->m_strName, "30375");
bool SkeletonTorso = Parts[LC_MFW_BODY] && !strcmp(Parts[LC_MFW_BODY]->m_strName, "6260");
if (Parts[LC_MFW_BODY3])
Root = lcMatrix44Translation(lcVector3(0, 0, 2.96f));
else
Root = lcMatrix44Translation(lcVector3(0, 0, 2.88f));
m_Matrices[LC_MFW_BODY] = lcMul(mSettings[LC_MFW_BODY][GetSelectionIndex(LC_MFW_BODY)].Offset, Root);
Matrices[LC_MFW_BODY] = lcMul(mSettings[LC_MFW_BODY][GetSelectionIndex(LC_MFW_BODY)].Offset, Root);
if (m_Info[LC_MFW_NECK])
if (Parts[LC_MFW_NECK])
{
m_Matrices[LC_MFW_NECK] = lcMul(mSettings[LC_MFW_NECK][GetSelectionIndex(LC_MFW_NECK)].Offset, Root);
Matrices[LC_MFW_NECK] = lcMul(mSettings[LC_MFW_NECK][GetSelectionIndex(LC_MFW_NECK)].Offset, Root);
HeadOffset = 0.08f;
}
if (m_Info[LC_MFW_HEAD])
if (Parts[LC_MFW_HEAD])
{
Mat = lcMatrix44RotationZ(-LC_DTOR * m_Angles[LC_MFW_HEAD]);
Mat = lcMatrix44RotationZ(-LC_DTOR * Angles[LC_MFW_HEAD]);
Mat.SetTranslation(lcVector3(0.0f, 0.0f, 0.96f + HeadOffset));
Mat = lcMul(mSettings[LC_MFW_HEAD][GetSelectionIndex(LC_MFW_HEAD)].Offset, Mat);
m_Matrices[LC_MFW_HEAD] = lcMul(Mat, Root);
Matrices[LC_MFW_HEAD] = lcMul(Mat, Root);
}
if (m_Info[LC_MFW_HATS])
if (Parts[LC_MFW_HATS])
{
Mat = lcMatrix44RotationZ(-LC_DTOR * m_Angles[LC_MFW_HATS]);
Mat = lcMatrix44RotationZ(-LC_DTOR * Angles[LC_MFW_HATS]);
Mat = lcMul(mSettings[LC_MFW_HATS][GetSelectionIndex(LC_MFW_HATS)].Offset, Mat);
m_Matrices[LC_MFW_HATS] = lcMul(Mat, m_Matrices[LC_MFW_HEAD]);
Matrices[LC_MFW_HATS] = lcMul(Mat, Matrices[LC_MFW_HEAD]);
}
if (m_Info[LC_MFW_HATS2])
if (Parts[LC_MFW_HATS2])
{
Mat = lcMatrix44RotationX(-LC_DTOR * m_Angles[LC_MFW_HATS2]);
Mat = lcMatrix44RotationX(-LC_DTOR * Angles[LC_MFW_HATS2]);
Mat = lcMul(mSettings[LC_MFW_HATS2][GetSelectionIndex(LC_MFW_HATS2)].Offset, Mat);
m_Matrices[LC_MFW_HATS2] = lcMul(Mat, m_Matrices[LC_MFW_HATS]);
Matrices[LC_MFW_HATS2] = lcMul(Mat, Matrices[LC_MFW_HATS]);
}
if (m_Info[LC_MFW_RARM])
if (Parts[LC_MFW_RARM])
{
Mat = lcMatrix44RotationX(-LC_DTOR * m_Angles[LC_MFW_RARM]);
Mat = lcMatrix44RotationX(-LC_DTOR * Angles[LC_MFW_RARM]);
if (DroidTorso || SkeletonTorso)
Mat2 = lcMatrix44Identity();
@ -1364,30 +1284,30 @@ void MinifigWizard::Calculate()
Mat = lcMul(mSettings[LC_MFW_RARM][GetSelectionIndex(LC_MFW_RARM)].Offset, Mat);
Mat = lcMul(Mat, Mat2);
m_Matrices[LC_MFW_RARM] = lcMul(Mat, Root);
Matrices[LC_MFW_RARM] = lcMul(Mat, Root);
}
if (m_Info[LC_MFW_RHAND])
if (Parts[LC_MFW_RHAND])
{
Mat = lcMatrix44RotationY(-LC_DTOR * m_Angles[LC_MFW_RHAND]);
Mat = lcMatrix44RotationY(-LC_DTOR * Angles[LC_MFW_RHAND]);
Mat2 = lcMatrix44RotationX(LC_DTOR * 45);
Mat = lcMul(mSettings[LC_MFW_RHAND][GetSelectionIndex(LC_MFW_RHAND)].Offset, Mat);
Mat = lcMul(Mat, Mat2);
Mat.SetTranslation(lcVector3(0.2f, -0.4f, -0.76f));
m_Matrices[LC_MFW_RHAND] = lcMul(Mat, m_Matrices[LC_MFW_RARM]);
Matrices[LC_MFW_RHAND] = lcMul(Mat, Matrices[LC_MFW_RARM]);
}
if (m_Info[LC_MFW_RHANDA])
if (Parts[LC_MFW_RHANDA])
{
Mat = lcMatrix44RotationZ(LC_DTOR * m_Angles[LC_MFW_RHANDA]);
Mat = lcMatrix44RotationZ(LC_DTOR * Angles[LC_MFW_RHANDA]);
Mat.SetTranslation(lcVector3(0, -0.4f, 0));
Mat = lcMul(mSettings[LC_MFW_RHANDA][GetSelectionIndex(LC_MFW_RHANDA)].Offset, Mat);
m_Matrices[LC_MFW_RHANDA] = lcMul(Mat, m_Matrices[LC_MFW_RHAND]);
Matrices[LC_MFW_RHANDA] = lcMul(Mat, Matrices[LC_MFW_RHAND]);
}
if (m_Info[LC_MFW_LARM])
if (Parts[LC_MFW_LARM])
{
Mat = lcMatrix44RotationX(-LC_DTOR * m_Angles[LC_MFW_LARM]);
Mat = lcMatrix44RotationX(-LC_DTOR * Angles[LC_MFW_LARM]);
if (DroidTorso || SkeletonTorso)
Mat2 = lcMatrix44Identity();
@ -1397,79 +1317,79 @@ void MinifigWizard::Calculate()
Mat = lcMul(mSettings[LC_MFW_LARM][GetSelectionIndex(LC_MFW_LARM)].Offset, Mat);
Mat = lcMul(Mat, Mat2);
m_Matrices[LC_MFW_LARM] = lcMul(Mat, Root);
Matrices[LC_MFW_LARM] = lcMul(Mat, Root);
}
if (m_Info[LC_MFW_LHAND])
if (Parts[LC_MFW_LHAND])
{
Mat = lcMatrix44RotationY(-LC_DTOR * m_Angles[LC_MFW_LHAND]);
Mat = lcMatrix44RotationY(-LC_DTOR * Angles[LC_MFW_LHAND]);
Mat2 = lcMatrix44RotationX(LC_DTOR * 45);
Mat = lcMul(mSettings[LC_MFW_LHAND][GetSelectionIndex(LC_MFW_LHAND)].Offset, Mat);
Mat = lcMul(Mat, Mat2);
Mat.SetTranslation(lcVector3(-0.2f, -0.4f, -0.76f));
m_Matrices[LC_MFW_LHAND] = lcMul(Mat, m_Matrices[LC_MFW_LARM]);
Matrices[LC_MFW_LHAND] = lcMul(Mat, Matrices[LC_MFW_LARM]);
}
if (m_Info[LC_MFW_LHANDA])
if (Parts[LC_MFW_LHANDA])
{
Mat = lcMatrix44RotationZ(LC_DTOR * m_Angles[LC_MFW_LHANDA]);
Mat = lcMatrix44RotationZ(LC_DTOR * Angles[LC_MFW_LHANDA]);
Mat.SetTranslation(lcVector3(0, -0.4f, 0));
Mat = lcMul(mSettings[LC_MFW_LHANDA][GetSelectionIndex(LC_MFW_LHANDA)].Offset, Mat);
m_Matrices[LC_MFW_LHANDA] = lcMul(Mat, m_Matrices[LC_MFW_LHAND]);
Matrices[LC_MFW_LHANDA] = lcMul(Mat, Matrices[LC_MFW_LHAND]);
}
if (m_Info[LC_MFW_BODY2])
if (Parts[LC_MFW_BODY2])
{
Mat = lcMatrix44Identity();
Mat.SetTranslation(lcVector3(0, 0, -1.28f));
Mat = lcMul(mSettings[LC_MFW_BODY2][GetSelectionIndex(LC_MFW_BODY2)].Offset, Mat);
m_Matrices[LC_MFW_BODY2] = lcMul(Mat, Root);
Matrices[LC_MFW_BODY2] = lcMul(Mat, Root);
}
if (m_Info[LC_MFW_BODY3])
if (Parts[LC_MFW_BODY3])
{
Mat = lcMatrix44Identity();
Mat.SetTranslation(lcVector3(0, 0, -1.28f));
Mat = lcMul(mSettings[LC_MFW_BODY3][GetSelectionIndex(LC_MFW_BODY3)].Offset, Mat);
m_Matrices[LC_MFW_BODY3] = lcMul(Mat, Root);
Matrices[LC_MFW_BODY3] = lcMul(Mat, Root);
}
if (m_Info[LC_MFW_RLEG])
if (Parts[LC_MFW_RLEG])
{
Mat = lcMatrix44RotationX(-LC_DTOR * m_Angles[LC_MFW_RLEG]);
Mat = lcMatrix44RotationX(-LC_DTOR * Angles[LC_MFW_RLEG]);
Mat.SetTranslation(lcVector3(0, 0, -1.76f));
Mat = lcMul(mSettings[LC_MFW_RLEG][GetSelectionIndex(LC_MFW_RLEG)].Offset, Mat);
m_Matrices[LC_MFW_RLEG] = lcMul(Mat, Root);
Matrices[LC_MFW_RLEG] = lcMul(Mat, Root);
}
if (m_Info[LC_MFW_RLEGA])
if (Parts[LC_MFW_RLEGA])
{
lcVector3 Center(-0.4f, -0.04f, -1.12f);
Mat = lcMatrix44RotationZ(LC_DTOR * m_Angles[LC_MFW_RLEGA]);
Mat = lcMatrix44RotationZ(LC_DTOR * Angles[LC_MFW_RLEGA]);
Mat2 = mSettings[LC_MFW_RLEGA][GetSelectionIndex(LC_MFW_RLEGA)].Offset;
Mat2.SetTranslation(lcMul31(-Center, Mat2));
Mat = lcMul(Mat2, Mat);
Mat.SetTranslation(lcMul31(Center, Mat2));
m_Matrices[LC_MFW_RLEGA] = lcMul(Mat, m_Matrices[LC_MFW_RLEG]);
Matrices[LC_MFW_RLEGA] = lcMul(Mat, Matrices[LC_MFW_RLEG]);
}
if (m_Info[LC_MFW_LLEG])
if (Parts[LC_MFW_LLEG])
{
Mat = lcMatrix44RotationX(-LC_DTOR * m_Angles[LC_MFW_LLEG]);
Mat = lcMatrix44RotationX(-LC_DTOR * Angles[LC_MFW_LLEG]);
Mat.SetTranslation(lcVector3(0, 0, -1.76f));
Mat = lcMul(mSettings[LC_MFW_LLEG][GetSelectionIndex(LC_MFW_LLEG)].Offset, Mat);
m_Matrices[LC_MFW_LLEG] = lcMul(Mat, Root);
Matrices[LC_MFW_LLEG] = lcMul(Mat, Root);
}
if (m_Info[LC_MFW_LLEGA])
if (Parts[LC_MFW_LLEGA])
{
lcVector3 Center(0.4f, -0.04f, -1.12f);
Mat = lcMatrix44RotationZ(LC_DTOR * m_Angles[LC_MFW_LLEGA]);
Mat = lcMatrix44RotationZ(LC_DTOR * Angles[LC_MFW_LLEGA]);
Mat2 = mSettings[LC_MFW_LLEGA][GetSelectionIndex(LC_MFW_LLEGA)].Offset;
Mat2.SetTranslation(lcMul31(-Center, Mat2));
Mat = lcMul(Mat2, Mat);
Mat.SetTranslation(lcMul31(Center, Mat2));
m_Matrices[LC_MFW_LLEGA] = lcMul(Mat, m_Matrices[LC_MFW_LLEG]);
Matrices[LC_MFW_LLEGA] = lcMul(Mat, Matrices[LC_MFW_LLEG]);
}
}
@ -1478,7 +1398,7 @@ int MinifigWizard::GetSelectionIndex(int Type) const
const ObjArray<lcMinifigPieceInfo>& InfoArray = mSettings[Type];
for (int Index = 0; Index < InfoArray.GetSize(); Index++)
if (InfoArray[Index].Info == m_Info[Type])
if (InfoArray[Index].Info == mMinifig->Parts[Type])
return Index;
return 0;
@ -1486,144 +1406,23 @@ int MinifigWizard::GetSelectionIndex(int Type) const
void MinifigWizard::SetSelectionIndex(int Type, int Index)
{
if (m_Info[Type])
m_Info[Type]->Release();
if (mMinifig->Parts[Type])
mMinifig->Parts[Type]->Release();
m_Info[Type] = mSettings[Type][Index].Info;
mMinifig->Parts[Type] = mSettings[Type][Index].Info;
if (m_Info[Type])
m_Info[Type]->AddRef();
if (mMinifig->Parts[Type])
mMinifig->Parts[Type]->AddRef();
Calculate();
}
void MinifigWizard::SetColor(int Type, int Color)
{
m_Colors[Type] = Color;
mMinifig->Colors[Type] = Color;
}
void MinifigWizard::SetAngle(int Type, float Angle)
{
m_Angles[Type] = Angle;
}
void MinifigWizard::GetMinifigNames(char ***names, int *count)
{
*count = m_MinifigCount;
*names = m_MinifigNames;
}
void MinifigWizard::SaveMinifig(const char* name)
{
char tmp[LC_PIECE_NAME_LEN];
int i, j;
// check if the name is already being used
for (i = 0; i < m_MinifigCount; i++)
if (strcmp(m_MinifigNames[i], name) == 0)
break;
if (i == m_MinifigCount)
{
m_MinifigCount++;
m_MinifigNames = (char**)realloc(m_MinifigNames, sizeof(char**)*m_MinifigCount);
m_MinifigTemplates = (char**)realloc(m_MinifigTemplates, sizeof(char**)*m_MinifigCount);
m_MinifigNames[i] = (char*)malloc(strlen(name) + 1);
strcpy(m_MinifigNames[i], name);
m_MinifigTemplates[i] = (char*)malloc(768);
}
strcpy(m_MinifigTemplates[i], "");
for (j = 0; j < LC_MFW_NUMITEMS; j++)
{
sprintf(tmp, "%d ", m_Colors[j]);
strcat(m_MinifigTemplates[i], tmp);
}
for (j = 0; j < LC_MFW_NUMITEMS; j++)
{
if (m_Info[j] != NULL)
sprintf(tmp, "%s ", m_Info[j]->m_strName);
else
strcpy(tmp, "None ");
strcat(m_MinifigTemplates[i], tmp);
}
for (j = 0; j < LC_MFW_NUMITEMS; j++)
{
sprintf(tmp, "%f ", m_Angles[j]);
strcat(m_MinifigTemplates[i], tmp);
}
}
bool MinifigWizard::LoadMinifig(const char* name)
{
char *ptr;
int i, j;
// check if the name is valid
for (i = 0; i < m_MinifigCount; i++)
if (strcmp(m_MinifigNames[i], name) == 0)
break;
if (i == m_MinifigCount)
{
// Sys_MessageBox("Unknown Minifig");
return false;
}
else
ptr = m_MinifigTemplates[i];
for (j = 0; j < LC_MFW_NUMITEMS; j++)
if (m_Info[j] != NULL)
m_Info[j]->Release();
for (j = 0; j < LC_MFW_NUMITEMS; j++)
m_Colors[j] = strtol(ptr, &ptr, 10);
for (j = 0; j < LC_MFW_NUMITEMS; j++)
{
char *endptr;
ptr++;
endptr = strchr(ptr, ' ');
*endptr = '\0';
m_Info[j] = lcGetPiecesLibrary()->FindPiece(ptr, false);
*endptr = ' ';
ptr = endptr;
if (m_Info[j] != NULL)
m_Info[j]->AddRef();
}
for (j = 0; j < LC_MFW_NUMITEMS; j++)
m_Angles[j] = (float)strtod(ptr, &ptr);
return true;
}
void MinifigWizard::DeleteMinifig(const char* name)
{
int i;
// check if the name is valid
for (i = 0; i < m_MinifigCount; i++)
if (strcmp(m_MinifigNames[i], name) == 0)
break;
if (i == m_MinifigCount)
{
Sys_MessageBox("Unknown Minifig");
return;
}
free(m_MinifigNames[i]);
free(m_MinifigTemplates[i]);
m_MinifigCount--;
for (; i < m_MinifigCount; i++)
{
m_MinifigNames[i] = m_MinifigNames[i+1];
m_MinifigTemplates[i] = m_MinifigTemplates[i+1];
}
mMinifig->Angles[Type] = Angle;
}

View file

@ -1,7 +1,7 @@
#ifndef _MINIFIG_H_
#define _MINIFIG_H_
#include "glwindow.h"
#include "lc_glwidget.h"
#include "lc_math.h"
#include "array.h"
@ -36,19 +36,27 @@ struct lcMinifigPieceInfo
lcMatrix44 Offset;
};
class MinifigWizard : public GLWindow
struct lcMinifig
{
PieceInfo* Parts[LC_MFW_NUMITEMS];
int Colors[LC_MFW_NUMITEMS];
float Angles[LC_MFW_NUMITEMS];
lcMatrix44 Matrices[LC_MFW_NUMITEMS];
};
class MinifigWizard : public lcGLWidget
{
public:
MinifigWizard (GLWindow *share);
MinifigWizard(lcMinifig* Minifig);
~MinifigWizard ();
void OnDraw ();
void OnLeftButtonDown(int x, int y, bool Control, bool Shift);
void OnLeftButtonUp(int x, int y, bool Control, bool Shift);
void OnLeftButtonDoubleClick(int x, int y, bool Control, bool Shift);
void OnRightButtonDown(int x, int y, bool Control, bool Shift);
void OnRightButtonUp(int x, int y, bool Control, bool Shift);
void OnMouseMove(int x, int y, bool Control, bool Shift);
void OnLeftButtonDown();
void OnLeftButtonUp();
void OnLeftButtonDoubleClick();
void OnRightButtonDown();
void OnRightButtonUp();
void OnMouseMove();
void OnInitialUpdate();
void Calculate();
@ -57,32 +65,16 @@ public:
void SetColor(int Type, int Color);
void SetAngle(int Type, float Angle);
void GetMinifigNames (char ***names, int *count);
void SaveMinifig (const char* name);
bool LoadMinifig (const char* name);
void DeleteMinifig (const char* name);
void ParseSettings(lcFile& Settings);
ObjArray<lcMinifigPieceInfo> mSettings[LC_MFW_NUMITEMS];
PieceInfo* m_Info[LC_MFW_NUMITEMS];
int m_Colors[LC_MFW_NUMITEMS];
float m_Angles[LC_MFW_NUMITEMS];
lcMatrix44 m_Matrices[LC_MFW_NUMITEMS];
lcMinifig* mMinifig;
protected:
// saved minifig templates
int m_MinifigCount;
char **m_MinifigNames;
char **m_MinifigTemplates;
// Mouse tracking.
int m_Tracking;
int m_DownX;
int m_DownY;
// Current camera settings.
float m_Distance;
float m_RotateX;
float m_RotateZ;

4
common/object.cpp Executable file → Normal file
View file

@ -1,12 +1,8 @@
// Base class for all drawable objects
//
#include "lc_global.h"
#include "lc_math.h"
#include <stdlib.h>
#include <float.h>
#include <math.h>
#include "globals.h"
#include "project.h"
#include "object.h"
#include "lc_file.h"

0
common/object.h Executable file → Normal file
View file

1221
common/opengl.cpp Executable file → Normal file

File diff suppressed because it is too large Load diff

1303
common/opengl.h Executable file → Normal file

File diff suppressed because it is too large Load diff

View file

@ -14,6 +14,7 @@
#include "group.h"
#include "project.h"
#include "lc_application.h"
#include "lc_library.h"
#define LC_PIECE_SAVE_VERSION 11 // LeoCAD 0.77
@ -69,7 +70,7 @@ void Piece::SetPieceInfo(PieceInfo* pPieceInfo)
mPieceInfo->AddRef();
}
bool Piece::FileLoad(lcFile& file, char* name)
bool Piece::FileLoad(lcFile& file)
{
lcuint8 version, ch;
@ -174,6 +175,7 @@ bool Piece::FileLoad(lcFile& file, char* name)
}
// Common to all versions.
char name[LC_PIECE_NAME_LEN];
if (version < 10)
{
memset(name, 0, LC_PIECE_NAME_LEN);
@ -182,6 +184,9 @@ bool Piece::FileLoad(lcFile& file, char* name)
else
file.ReadBuffer(name, LC_PIECE_NAME_LEN);
PieceInfo* pInfo = lcGetPiecesLibrary()->FindPiece(name, true);
SetPieceInfo(pInfo);
// 11 (0.77)
if (version < 11)
{
@ -250,7 +255,7 @@ bool Piece::FileLoad(lcFile& file, char* name)
return true;
}
void Piece::FileSave(lcFile& file, Group* pGroups)
void Piece::FileSave(lcFile& file) const
{
file.WriteU8(LC_PIECE_SAVE_VERSION);
@ -275,6 +280,7 @@ void Piece::FileSave(lcFile& file, Group* pGroups)
if (m_pGroup != NULL)
{
Group* pGroups = lcGetActiveProject()->m_pGroups;
for (i = 0; pGroups; pGroups = pGroups->m_pNext)
{
if (m_pGroup == pGroups)

View file

@ -49,7 +49,7 @@ public:
{ return (m_nState & LC_PIECE_FOCUSED) != 0; }
const char* GetName() const
{ return m_strName; };
{ return m_strName; }
virtual void MinIntersectDist(lcClickLine* ClickLine);
bool IsVisible(unsigned short nTime, bool bAnimation);
@ -57,8 +57,8 @@ public:
void CreateName(Piece* pPiece);
void CompareBoundingBox(float box[6]);
void SetPieceInfo(PieceInfo* pPieceInfo);
bool FileLoad(lcFile& file, char* name);
void FileSave(lcFile& file, Group* pGroups);
bool FileLoad(lcFile& file);
void FileSave(lcFile& file) const;
void UpdatePosition(unsigned short nTime, bool bAnimation);
void Move(unsigned short nTime, bool bAnimation, bool bAddKey, float dx, float dy, float dz);

View file

@ -96,7 +96,7 @@ void PieceInfo::Load()
lcGetPiecesLibrary()->GeneratePiece(this);
else
lcGetPiecesLibrary()->LoadPiece(this);
}
}
void PieceInfo::Unload()
{

View file

@ -1,17 +1,12 @@
//
// Piece Preview window
//
#include "lc_global.h"
#include "preview.h"
#include "globals.h"
#include "project.h"
#include "pieceinf.h"
#include "system.h"
#include "lc_application.h"
#include "mainwnd.h"
PiecePreview::PiecePreview(GLWindow *share)
: GLWindow(share)
PiecePreview::PiecePreview()
{
m_PieceInfo = NULL;
m_RotateX = 60.0f;
@ -36,8 +31,8 @@ void PiecePreview::OnDraw()
glPolygonOffset(0.5f, 0.1f);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
float aspect = (float)m_nWidth/(float)m_nHeight;
glViewport(0, 0, m_nWidth, m_nHeight);
float aspect = (float)mWidth/(float)mHeight;
glViewport(0, 0, mWidth, mHeight);
lcVector3 Eye(0.0f, 0.0f, 1.0f);
@ -64,7 +59,7 @@ void PiecePreview::OnDraw()
float *bg = lcGetActiveProject()->GetBackgroundColor();
glClearColor(bg[0], bg[1], bg[2], bg[3]);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
m_PieceInfo->RenderPiece(lcGetActiveProject()->GetCurrentColor());
m_PieceInfo->RenderPiece(gMainWindow->mColorIndex);
}
void PiecePreview::SetCurrentPiece(PieceInfo *pInfo)
@ -84,18 +79,18 @@ void PiecePreview::SetCurrentPiece(PieceInfo *pInfo)
}
}
void PiecePreview::OnLeftButtonDown(int x, int y, bool Control, bool Shift)
void PiecePreview::OnLeftButtonDown()
{
if (m_Tracking == LC_TRACK_NONE)
{
m_DownX = x;
m_DownY = y;
m_DownX = mInputState.x;
m_DownY = mInputState.y;
m_Tracking = LC_TRACK_LEFT;
CaptureMouse();
}
}
void PiecePreview::OnLeftButtonUp(int x, int y, bool Control, bool Shift)
void PiecePreview::OnLeftButtonUp()
{
if (m_Tracking == LC_TRACK_LEFT)
{
@ -104,24 +99,24 @@ void PiecePreview::OnLeftButtonUp(int x, int y, bool Control, bool Shift)
}
}
void PiecePreview::OnLeftButtonDoubleClick(int x, int y, bool Control, bool Shift)
void PiecePreview::OnLeftButtonDoubleClick()
{
m_AutoZoom = true;
Redraw();
}
void PiecePreview::OnRightButtonDown(int x, int y, bool Control, bool Shift)
void PiecePreview::OnRightButtonDown()
{
if (m_Tracking == LC_TRACK_NONE)
{
m_DownX = x;
m_DownY = y;
m_DownX = mInputState.x;
m_DownY = mInputState.y;
m_Tracking = LC_TRACK_RIGHT;
CaptureMouse();
}
}
void PiecePreview::OnRightButtonUp(int x, int y, bool Control, bool Shift)
void PiecePreview::OnRightButtonUp()
{
if (m_Tracking == LC_TRACK_RIGHT)
{
@ -130,35 +125,35 @@ void PiecePreview::OnRightButtonUp(int x, int y, bool Control, bool Shift)
}
}
void PiecePreview::OnMouseMove(int x, int y, bool Control, bool Shift)
void PiecePreview::OnMouseMove()
{
if (m_Tracking == LC_TRACK_LEFT)
{
// Rotate.
m_RotateZ += x - m_DownX;
m_RotateX += y - m_DownY;
m_RotateZ += mInputState.x - m_DownX;
m_RotateX += mInputState.y - m_DownY;
if (m_RotateX > 179.5f)
m_RotateX = 179.5f;
else if (m_RotateX < 0.5f)
m_RotateX = 0.5f;
m_DownX = x;
m_DownY = y;
m_DownX = mInputState.x;
m_DownY = mInputState.y;
Redraw();
}
else if (m_Tracking == LC_TRACK_RIGHT)
{
// Zoom.
m_Distance += (float)(m_DownY - y) * 0.2f;
m_Distance += (float)(m_DownY - mInputState.y) * 0.2f;
m_AutoZoom = false;
if (m_Distance < 0.5f)
m_Distance = 0.5f;
m_DownX = x;
m_DownY = y;
m_DownX = mInputState.x;
m_DownY = mInputState.y;
Redraw();
}

View file

@ -1,23 +1,23 @@
#ifndef _PREVIEW_H_
#define _PREVIEW_H_
#include "glwindow.h"
#include "lc_glwidget.h"
class PieceInfo;
class PiecePreview : public GLWindow
class PiecePreview : public lcGLWidget
{
public:
PiecePreview(GLWindow *share);
PiecePreview();
virtual ~PiecePreview();
void OnDraw();
void OnLeftButtonDown(int x, int y, bool Control, bool Shift);
void OnLeftButtonUp(int x, int y, bool Control, bool Shift);
void OnLeftButtonDoubleClick(int x, int y, bool Control, bool Shift);
void OnRightButtonDown(int x, int y, bool Control, bool Shift);
void OnRightButtonUp(int x, int y, bool Control, bool Shift);
void OnMouseMove(int x, int y, bool Control, bool Shift);
void OnLeftButtonDown();
void OnLeftButtonUp();
void OnLeftButtonDoubleClick();
void OnRightButtonDown();
void OnRightButtonUp();
void OnMouseMove();
PieceInfo* GetCurrentPiece() const
{ return m_PieceInfo; }

File diff suppressed because it is too large Load diff

View file

@ -2,10 +2,78 @@
#define _PROJECT_H_
#include "object.h"
#include "typedefs.h"
#include "opengl.h"
#include "array.h"
#include "lc_math.h"
#include "lc_commands.h"
//#define DET_BACKFACES 0x00001 // Draw backfaces
//#define DET_DEPTH 0x00002 // Enable depth test
//#define DET_CLEAR 0x00004 // Use clear colors
#define LC_DET_LIGHTING 0x00008 // Lighting
//#define LC_DET_SMOOTH 0x00010 // Smooth shading
//#define DET_STUDS 0x00020 // Draw studs
//#define DET_WIREFRAME 0x00040 // Wireframe
//#define LC_DET_ANTIALIAS 0x00080 // Turn on anti-aliasing
#define LC_DET_BRICKEDGES 0x00100 // Draw lines
//#define LC_DET_DITHER 0x00200 // Enable dithering
//#define LC_DET_BOX_FILL 0x00400 // Filled boxes
//#define LC_DET_HIDDEN_LINE 0x00800 // Remove hidden lines
//#define DET_STUDS_BOX 0x01000 // Draw studs as boxes
//#define LC_DET_LINEAR 0x02000 // Linear filtering
#define LC_DET_FAST 0x04000 // Fast rendering (boxes)
//#define LC_DET_BACKGROUND 0x08000 // Background rendering
//#define LC_DET_SCREENDOOR 0x10000 // No alpha blending
#define LC_DRAW_AXIS 0x0001 // Orientation icon
#define LC_DRAW_GRID 0x0002 // Grid
#define LC_DRAW_SNAP_A 0x0004 // Snap Angle
#define LC_DRAW_SNAP_X 0x0008 // Snap X
#define LC_DRAW_SNAP_Y 0x0010 // Snap Y
#define LC_DRAW_SNAP_Z 0x0020 // Snap Z
#define LC_DRAW_SNAP_XYZ (LC_DRAW_SNAP_X | LC_DRAW_SNAP_Y | LC_DRAW_SNAP_Z)
#define LC_DRAW_GLOBAL_SNAP 0x0040 // Don't allow relative snap.
//#define LC_DRAW_MOVE 0x0080 // Switch to move after insert
#define LC_DRAW_LOCK_X 0x0100 // Lock X
#define LC_DRAW_LOCK_Y 0x0200 // Lock Y
#define LC_DRAW_LOCK_Z 0x0400 // Lock Z
#define LC_DRAW_LOCK_XYZ (LC_DRAW_LOCK_X | LC_DRAW_LOCK_Y | LC_DRAW_LOCK_Z)
#define LC_DRAW_MOVEAXIS 0x0800 // Move on fixed axis
//#define LC_DRAW_PREVIEW 0x1000 // Show piece position
#define LC_DRAW_CM_UNITS 0x2000 // Use centimeters
//#define LC_DRAW_3DMOUSE 0x4000 // Mouse moves in all directions
// #define RENDER_FAST 0x001
// #define RENDER_BACKGROUND 0x002
#define LC_SCENE_FOG 0x004 // Enable fog
// #define RENDER_FOG_BG 0x008 // Use bg color for fog
#define LC_SCENE_BG 0x010 // Draw bg image
// #define RENDER_BG_FAST 0x020
#define LC_SCENE_BG_TILE 0x040 // Tile bg image
#define LC_SCENE_FLOOR 0x080 // Render floor
#define LC_SCENE_GRADIENT 0x100 // Draw gradient
#define LC_HTML_SINGLEPAGE 0x01
#define LC_HTML_INDEX 0x02
#define LC_HTML_IMAGES 0x04
#define LC_HTML_LISTEND 0x08
#define LC_HTML_LISTSTEP 0x10
#define LC_HTML_HIGHLIGHT 0x20
//#define LC_HTML_HTMLEXT 0x40
//#define LC_HTML_LISTID 0x80
enum LC_NOTIFY
{
LC_CAPTURE_LOST
};
enum LC_TRANSFORM_TYPE
{
LC_TRANSFORM_ABSOLUTE_TRANSLATION,
LC_TRANSFORM_RELATIVE_TRANSLATION,
LC_TRANSFORM_ABSOLUTE_ROTATION,
LC_TRANSFORM_RELATIVE_ROTATION
};
enum LC_MOUSE_TRACK
{
@ -39,7 +107,7 @@ enum LC_OVERLAY_MODES
LC_OVERLAY_ROTATE_VIEW_X,
LC_OVERLAY_ROTATE_VIEW_Y,
LC_OVERLAY_ROTATE_VIEW_Z,
LC_OVERLAY_ROTATE_VIEW_XYZ,
LC_OVERLAY_ROTATE_VIEW_XYZ
};
class Piece;
@ -61,7 +129,7 @@ struct LC_UNDOINFO
lcMemFile file;
char strText[21];
LC_UNDOINFO* pNext;
LC_UNDOINFO() { pNext = NULL; };
LC_UNDOINFO() { pNext = NULL; }
};
struct LC_FILEENTRY
@ -77,6 +145,51 @@ struct lcPiecesUsedEntry
int Count;
};
struct lcSearchOptions
{
bool MatchInfo;
bool MatchColor;
bool MatchName;
PieceInfo* Info;
int ColorIndex;
char Name[256];
};
enum lcObjectProperty
{
LC_PART_POSITION,
LC_PART_ROTATION,
LC_PART_SHOW,
LC_PART_HIDE,
LC_PART_COLOR,
LC_PART_ID,
LC_CAMERA_POSITION,
LC_CAMERA_TARGET,
LC_CAMERA_UP,
LC_CAMERA_FOV,
LC_CAMERA_NEAR,
LC_CAMERA_FAR,
LC_CAMERA_NAME
};
enum LC_ACTIONS
{
LC_ACTION_INSERT,
LC_ACTION_LIGHT,
LC_ACTION_SPOTLIGHT,
LC_ACTION_CAMERA,
LC_ACTION_SELECT,
LC_ACTION_MOVE,
LC_ACTION_ROTATE,
LC_ACTION_ERASER,
LC_ACTION_PAINT,
LC_ACTION_ZOOM,
LC_ACTION_PAN,
LC_ACTION_ROTATE_VIEW,
LC_ACTION_ROLL,
LC_ACTION_ZOOM_REGION
};
class Project
{
public:
@ -88,8 +201,6 @@ public:
public:
bool IsModified()
{ return m_bModified; }
void SetModifiedFlag(bool bModified)
{ m_bModified = bModified; }
// Access to protected members
unsigned char GetLastStep();
@ -99,10 +210,16 @@ public:
{ m_bAnimation = Anim; } // only to be called from lcApplication::Initialize()
unsigned short GetCurrentTime ()
{ return m_bAnimation ? m_nCurFrame : m_nCurStep; }
void SetCurrentTime(unsigned short Time)
{
if (m_bAnimation)
m_nCurFrame = Time;
else
m_nCurStep = (unsigned char)Time;
CalculateStep();
}
void SetCurrentPiece(PieceInfo* pInfo)
{ m_pCurPiece = pInfo; }
int GetCurrentColor () const
{ return m_nCurColor; }
float* GetBackgroundColor()
{ return m_fBackground; }
unsigned long GetSnap() const
@ -110,8 +227,8 @@ public:
int GetOverlayMode() const
{ return m_OverlayMode; }
void GetSnapIndex(int* SnapXY, int* SnapZ, int* SnapAngle) const;
void GetSnapText(char* SnapXY, char* SnapZ, char* SnapAngle) const;
void GetSnapDistance(float* SnapXY, float* SnapZ) const;
void GetSnapDistanceText(char* SnapXY, char* SnapZ) const;
void GetTimeRange(int* from, int* to)
{
*from = m_bAnimation ? m_nCurFrame : m_nCurStep;
@ -132,6 +249,8 @@ public:
void DeleteContents(bool bUndo); // delete doc items etc
void LoadDefaults(bool cameras);
void BeginPieceDrop(PieceInfo* Info);
void OnPieceDropMove(int x, int y);
void EndPieceDrop(bool Accept);
void BeginColorDrop();
void GetPiecesUsed(ObjArray<lcPiecesUsedEntry>& PiecesUsed) const;
@ -143,6 +262,8 @@ public:
Object* GetFocusObject() const;
Group* AddGroup (const char* name, Group* pParent, float x, float y, float z);
void TransformSelectedObjects(LC_TRANSFORM_TYPE Type, const lcVector3& Transform);
void ModifyObject(Object* Object, lcObjectProperty Property, void* Value);
void ZoomActiveView(int Amount);
void AddView(View* view);
void RemoveView(View* view);
@ -160,13 +281,12 @@ public:
Group* m_pGroups;
Terrain* m_pTerrain;
// Implementation
protected:
// default implementation
char m_strTitle[LC_MAXPATH];
char m_strPathName[LC_MAXPATH];
bool m_bModified; // changed since last saved
bool m_bModified;
// Implementation
protected:
View* m_ActiveView;
PtrArray<View> m_ViewList;
@ -183,9 +303,6 @@ protected:
bool m_bUndoOriginal;
void CheckPoint (const char* text);
lcFile* m_pClipboard[10];
unsigned char m_nCurClipboard;
void AddPiece(Piece* pPiece);
void RemovePiece(Piece* pPiece);
bool RemoveSelectedObjects();
@ -196,6 +313,9 @@ protected:
void SelectAndFocusNone(bool bFocusOnly);
void CalculateStep();
void FindPiece(bool FindFirst, bool SearchForward);
lcSearchOptions mSearchOptions;
// Movement.
bool MoveSelectedObjects(lcVector3& Move, lcVector3& Remainder, bool Snap, bool Lock);
bool RotateSelectedObjects(lcVector3& Delta, lcVector3& Remainder, bool Snap, bool Lock);
@ -216,7 +336,8 @@ protected:
void RenderOverlays(View* view);
void RenderInitialize();
void CreateHTMLPieceList(FILE* f, int nStep, bool bImages, bool ShowID, const char* ext);
void CreateHTMLPieceList(FILE* f, int nStep, bool bImages, const char* ext);
void Export3DStudio();
void ZoomExtents(int FirstView, int LastView);
bool m_bStopRender;
@ -245,17 +366,15 @@ protected:
void RemoveEmptyGroups();
public:
// Call these functions from each OS
void OnLeftButtonDown(View* view, int x, int y, bool Control, bool Shift);
void OnLeftButtonUp(View* view, int x, int y, bool Control, bool Shift);
void OnLeftButtonDoubleClick(View* view, int x, int y, bool Control, bool Shift);
void OnMiddleButtonDown(View* view, int x, int y, bool Control, bool Shift);
void OnMiddleButtonUp(View* view, int x, int y, bool Control, bool Shift);
void OnRightButtonDown(View* view, int x, int y, bool Control, bool Shift);
void OnRightButtonUp(View* view, int x, int y, bool Control, bool Shift);
void OnMouseMove(View* view, int x, int y, bool Control, bool Shift);
void OnMouseWheel(View* view, int x, int y, float Direction, bool Control, bool Shift);
bool OnKeyDown(char nKey, bool Control, bool Shift);
void OnLeftButtonDown(View* view);
void OnLeftButtonUp(View* view);
void OnLeftButtonDoubleClick(View* view);
void OnMiddleButtonDown(View* view);
void OnMiddleButtonUp(View* view);
void OnRightButtonDown(View* view);
void OnRightButtonUp(View* view);
void OnMouseMove(View* view);
void OnMouseWheel(View* view, float Direction);
void SetAction(int Action);
int GetCurAction() const
@ -265,17 +384,14 @@ public:
int GetAction() const;
void HandleNotify(LC_NOTIFY id, unsigned long param);
void HandleCommand(LC_COMMANDS id, unsigned long nParam);
void HandleMessage(int Message, void* Data);
void HandleCommand(LC_COMMANDS id);
protected:
// State variables
int mTransformType;
int m_nCurAction;
int m_PreviousAction;
bool m_RestoreAction;
PieceInfo* m_pCurPiece;
PieceInfo* m_PreviousPiece;
unsigned char m_nCurColor;
PieceInfo* mDropPiece;
bool m_bAnimation;
bool m_bAddKeys;
unsigned char m_nFPS;
@ -302,14 +418,12 @@ protected:
GLuint m_nGridList;
unsigned long m_nAutosave;
unsigned long m_nSaveTimer;
char m_strModelsPath[LC_MAXPATH];
char m_strBackground[LC_MAXPATH];
lcTexture* m_pBackground;
protected:
// File load/save implementation.
bool DoSave(char* PathName, bool bReplace);
bool DoFileSave();
bool DoSave(const char* FileName);
bool FileLoad(lcFile* file, bool bUndo, bool bMerge);
void FileSave(lcFile* file, bool bUndo);
void FileReadLDraw(lcFile* file, const lcMatrix44& CurrentTransform, int* nOk, int DefColor, int* nStep, PtrArray<LC_FILEENTRY>& FileArray);
@ -321,16 +435,7 @@ public:
bool OnOpenDocument(const char* FileName);
bool OpenProject(const char* FileName);
bool SaveModified();
protected:
// mail enabling
// void OnFileSendMail();
// void OnUpdateFileSendMail(CCmdUI* pCmdUI);
// TODO: Fix ! This is a hack to make things work now
friend class CCADView;
friend void PrintPiecesThread(void* pv);
friend void Export3DStudio();
void SetModifiedFlag(bool Modified);
};
#endif // _PROJECT_H_

View file

@ -1,662 +0,0 @@
///////////////////////////////////////
// DL1 Quantization
#include "lc_global.h"
#include <stdlib.h>
#include <math.h>
#include <memory.h>
#include <string.h>
struct CUBE
{
unsigned long r, g, b;
unsigned long pixel_count;
unsigned long pixels_in_cube;
unsigned char children;
unsigned char palette_index;
};
struct FCUBE
{
unsigned char level;
unsigned short index;
};
struct CLOSEST_INFO
{
unsigned char palette_index, red, green, blue;
unsigned long distance;
unsigned long squares[255+255+1];
};
//#define FAST // improves speed but uses a lot of memory
#define QUAL1 // slightly improves quality
//#define QUAL2 // slightly improves quality
//#define DITHER1 // 1-val error diffusion dither
#define DITHER2 // 2-val error diffusion dither
//#define DITHER4 // 4-val error diffusion dither (Floyd-Steinberg)
#define DITHER_MAX 20
static void dlq_finish();
static int build_table(unsigned char *image, unsigned long pixels);
static void fixheap(unsigned long id);
static void reduce_table(int num_colors);
static void set_palette(int index, int level);
static void closest_color(int index, int level);
static int quantize_image(unsigned char *in, unsigned char *out, int width, int height, int dither);
static int bestcolor(int r, int g, int b);
static unsigned char palette[3][256];
static CUBE *rgb_table[6];
static unsigned short r_offset[256], g_offset[256], b_offset[256];
static CLOSEST_INFO c_info;
static int tot_colors, pal_index;
static unsigned long *squares;
static FCUBE *heap = NULL;
static short *dl_image = NULL;
bool dl1quant(unsigned char *inbuf, unsigned char *outbuf, int width, int height, int quant_to, int dither, unsigned char userpal[3][256])
{
int i;
// dlq_init
for (i = 0; i < 6; i++)
rgb_table[i]=NULL;
tot_colors=0;
pal_index=0;
heap = NULL;
dl_image = NULL;
for (i = 0; i < 256; i++)
{
r_offset[i] = (i & 128) << 7 | (i & 64) << 5 | (i & 32) << 3 |
(i & 16) << 1 | (i & 8) >> 1;
g_offset[i] = (i & 128) << 6 | (i & 64) << 4 | (i & 32) << 2 |
(i & 16) << 0 | (i & 8) >> 2;
b_offset[i] = (i & 128) << 5 | (i & 64) << 3 | (i & 32) << 1 |
(i & 16) >> 1 | (i & 8) >> 3;
}
c_info.palette_index=0;
c_info.red=0;
c_info.green=0;
c_info.blue=0;
c_info.distance=0;
for (i = (-255); i <= 255; i++)
c_info.squares[i+255] = i*i;
for (i = 0; i < 256; i++)
{
palette[0][i] = 0;
palette[1][i] = 0;
palette[2][i] = 0;
}
squares = c_info.squares + 255;
// dlq_start
rgb_table[0] = (CUBE*)calloc(sizeof(CUBE), 1);
rgb_table[1] = (CUBE*)calloc(sizeof(CUBE), 8);
rgb_table[2] = (CUBE*)calloc(sizeof(CUBE), 64);
rgb_table[3] = (CUBE*)calloc(sizeof(CUBE), 512);
rgb_table[4] = (CUBE*)calloc(sizeof(CUBE), 4096);
rgb_table[5] = (CUBE*)calloc(sizeof(CUBE), 32768);
for (i = 0; i <= 5; i++)
if (rgb_table[i] == NULL)
{
dlq_finish();
return false;
}
pal_index = 0;
if (build_table(inbuf, width*height) == 0)
{
dlq_finish();
return false;
}
reduce_table(quant_to);
set_palette(0, 0);
if (quantize_image(inbuf, outbuf, width, height, dither) == 0)
{
dlq_finish();
return false;
}
dlq_finish();
for (i = 0; i < 256; i++)
{
userpal[0][i] = palette[0][i];
userpal[1][i] = palette[1][i];
userpal[2][i] = palette[2][i];
}
return true;
}
static void dlq_finish(void)
{
for (int i = 0;i < 6;i++)
{
if (rgb_table[i] != NULL)
{
free(rgb_table[i]);
rgb_table[i] = NULL;
}
}
if (heap != NULL)
{
free(heap);
heap = NULL;
}
if (dl_image != NULL)
{
free(dl_image);
dl_image = NULL;
}
memset(&c_info, 0, sizeof(CLOSEST_INFO));
tot_colors=pal_index=0;
}
// returns 1 on success, 0 on failure
static int build_table(unsigned char *image, unsigned long pixels)
{
unsigned long i = 0, index = 0, cur_count = 0, head = 0, tail = 0;
long j = 0;
heap = (FCUBE *) malloc(sizeof(FCUBE) * 32769);
if (heap == NULL)
return 0;
#ifdef FAST
dl_image = malloc(sizeof(short) * pixels);
if (dl_image == NULL)
return 0;
#endif
for (i = 0; i < pixels; i++)
{
#ifdef FAST
dl_image[i] = index = r_offset[image[0]] + g_offset[image[1]] + b_offset[image[2]];
#else
index = r_offset[image[0]] + g_offset[image[1]] + b_offset[image[2]];
#endif
#ifdef QUAL1
rgb_table[5][index].r += image[0];
rgb_table[5][index].g += image[1];
rgb_table[5][index].b += image[2];
#endif
rgb_table[5][index].pixel_count++;
image += 3;
}
tot_colors = 0;
for (i = 0; i < 32768; i++)
{
cur_count = rgb_table[5][i].pixel_count;
if (cur_count)
{
heap[++tot_colors].level = 5;
heap[tot_colors].index = (unsigned short)i;
rgb_table[5][i].pixels_in_cube = cur_count;
#ifndef QUAL1
rgb_table[5][i].r = cur_count * (((i & 0x4000) >> 7 |
(i & 0x0800) >> 5 | (i & 0x0100) >> 3 |
(i & 0x0020) >> 1 | (i & 0x0004) << 1) + 4);
rgb_table[5][i].g = cur_count * (((i & 0x2000) >> 6 |
(i & 0x0400) >> 4 | (i & 0x0080) >> 2 |
(i & 0x0010) >> 0 | (i & 0x0002) << 2) + 4);
rgb_table[5][i].b = cur_count * (((i & 0x1000) >> 5 |
(i & 0x0200) >> 3 | (i & 0x0040) >> 1 |
(i & 0x0008) << 1 | (i & 0x0001) << 3) + 4);
#endif
head = i;
for (j = 4; j >= 0; j--)
{
tail = head & 0x7;
head >>= 3;
rgb_table[j][head].pixels_in_cube += cur_count;
rgb_table[j][head].children |= 1 << tail;
}
}
}
for (i = tot_colors; i > 0; i--)
fixheap(i);
return 1;
}
static void fixheap(unsigned long heapid)
{
unsigned char thres_level = heap[heapid].level;
unsigned long thres_index = heap[heapid].index, index = 0;
unsigned long half_totc = tot_colors >> 1;
unsigned long thres_val = rgb_table[thres_level][thres_index].pixels_in_cube;
while (heapid <= half_totc)
{
index = heapid << 1;
if (index < (unsigned long)tot_colors)
if (rgb_table[heap[index].level][heap[index].index].pixels_in_cube
> rgb_table[heap[index+1].level][heap[index+1].index].pixels_in_cube)
index++;
if (thres_val <= rgb_table[heap[index].level][heap[index].index].pixels_in_cube)
break;
else {
heap[heapid] = heap[index];
heapid = index;
}
}
heap[heapid].level = thres_level;
heap[heapid].index = (unsigned short)thres_index;
}
static void reduce_table(int num_colors)
{
while (tot_colors > num_colors)
{
unsigned char tmp_level = heap[1].level, t_level = (tmp_level - 1) > 0 ? (tmp_level - 1) : 0;
unsigned long tmp_index = heap[1].index, t_index = tmp_index >> 3;
if (rgb_table[t_level][t_index].pixel_count)
heap[1] = heap[tot_colors--];
else
{
heap[1].level = t_level;
heap[1].index = (unsigned short)t_index;
}
rgb_table[t_level][t_index].pixel_count += rgb_table[tmp_level][tmp_index].pixel_count;
rgb_table[t_level][t_index].r += rgb_table[tmp_level][tmp_index].r;
rgb_table[t_level][t_index].g += rgb_table[tmp_level][tmp_index].g;
rgb_table[t_level][t_index].b += rgb_table[tmp_level][tmp_index].b;
rgb_table[t_level][t_index].children &= ~(1 << (tmp_index & 0x7));
fixheap(1);
}
}
static void set_palette(int index, int level)
{
int i;
if (rgb_table[level][index].children)
for (i = 7; i >= 0; i--)
if (rgb_table[level][index].children & (1 << i))
set_palette((index << 3) + i, level + 1);
if (rgb_table[level][index].pixel_count)
{
unsigned long r_sum, g_sum, b_sum, sum;
rgb_table[level][index].palette_index = pal_index;
r_sum = rgb_table[level][index].r;
g_sum = rgb_table[level][index].g;
b_sum = rgb_table[level][index].b;
sum = rgb_table[level][index].pixel_count;
palette[0][pal_index] = (unsigned char)((r_sum + (sum >> 1)) / sum);
palette[1][pal_index] = (unsigned char)((g_sum + (sum >> 1)) / sum);
palette[2][pal_index] = (unsigned char)((b_sum + (sum >> 1)) / sum);
pal_index++;
}
}
static void closest_color(int index, int level)
{
int i;
if (rgb_table[level][index].children)
for (i = 7; i >= 0; i--)
if (rgb_table[level][index].children & (1 << i))
closest_color((index << 3) + i, level + 1);
if (rgb_table[level][index].pixel_count)
{
long dist, r_dist, g_dist, b_dist;
unsigned char pal_num = rgb_table[level][index].palette_index;
// Determine if this color is "closest".
r_dist = palette[0][pal_num] - c_info.red;
g_dist = palette[1][pal_num] - c_info.green;
b_dist = palette[2][pal_num] - c_info.blue;
dist = squares[r_dist] + squares[g_dist] + squares[b_dist];
if (dist < (long)c_info.distance)
{
c_info.distance = dist;
c_info.palette_index = pal_num;
}
}
}
// returns 1 on success, 0 on failure
static int quantize_image(unsigned char *in, unsigned char *out, int width, int height, int dither)
{
if (!dither)
{
unsigned long i = 0, pixels = width * height;
unsigned short level = 0, index = 0;
unsigned char tmp_r = 0, tmp_g = 0, tmp_b = 0, cube = 0;
unsigned char *lookup = NULL;
lookup = (unsigned char*)malloc(sizeof(char) * 32768);
if (lookup == NULL)
return 0;
for (i = 0; i < 32768; i++)
if (rgb_table[5][i].pixel_count)
{
tmp_r = (unsigned char)((i & 0x4000) >> 7 | (i & 0x0800) >> 5 |
(i & 0x0100) >> 3 | (i & 0x0020) >> 1 |
(i & 0x0004) << 1);
tmp_g = (unsigned char)((i & 0x2000) >> 6 | (i & 0x0400) >> 4 |
(i & 0x0080) >> 2 | (i & 0x0010) >> 0 |
(i & 0x0002) << 2);
tmp_b = (unsigned char)((i & 0x1000) >> 5 | (i & 0x0200) >> 3 |
(i & 0x0040) >> 1 | (i & 0x0008) << 1 |
(i & 0x0001) << 3);
#ifdef QUAL2
lookup[i] = bestcolor(tmp_r, tmp_g, tmp_b);
#else
c_info.red = tmp_r + 4;
c_info.green = tmp_g + 4;
c_info.blue = tmp_b + 4;
level = 0;
index = 0;
for (;;) {
cube = (tmp_r&128) >> 5 | (tmp_g&128) >> 6 | (tmp_b&128) >> 7;
if ((rgb_table[level][index].children & (1 << cube)) == 0) {
c_info.distance = (unsigned long)~0L;
closest_color(index, level);
lookup[i] = c_info.palette_index;
break;
}
level++;
index = (index << 3) + cube;
tmp_r <<= 1;
tmp_g <<= 1;
tmp_b <<= 1;
}
#endif
}
for (i = 0; i < pixels; i++)
{
#ifdef FAST
out[i] = lookup[dl_image[i]];
#else
out[i] = lookup[r_offset[in[0]] + g_offset[in[1]] + b_offset[in[2]]];
in += 3;
#endif
}
free(lookup);
}
else // dither
{
#if defined(DITHER2) || defined(DITHER4)
long i = 0, j = 0;
long r_pix = 0, g_pix = 0, b_pix = 0;
long offset = 0, dir = 0;
long odd_scanline = 0;
long err_len = (width + 2) * 3;
unsigned char *range_tbl = NULL, *range = NULL;
short *lookup = NULL, *erowerr = NULL, *orowerr = NULL;
short *thisrowerr = NULL, *nextrowerr = NULL;
char *dith_max_tbl = NULL, *dith_max = NULL;
lookup = (short*)malloc(sizeof(short) * 32768);
erowerr = (short*)malloc(sizeof(short) * err_len);
orowerr = (short*)malloc(sizeof(short) * err_len);
range_tbl = (unsigned char*)malloc(3 * 256);
range = range_tbl + 256;
dith_max_tbl= (char*)malloc(512);
dith_max = dith_max_tbl + 256;
if (range_tbl == NULL || lookup == NULL || erowerr == NULL || orowerr == NULL || dith_max_tbl == NULL)
{
if (range_tbl != NULL)
{
free(range_tbl);
range_tbl=NULL;
}
if (lookup != NULL)
{
free(lookup);
lookup=NULL;
}
if (erowerr != NULL)
{
free(erowerr);
erowerr=NULL;
}
if (orowerr != NULL)
{
free(orowerr);
orowerr=NULL;
}
if (dith_max_tbl != NULL)
{
free(dith_max_tbl);
dith_max_tbl=NULL;
}
return 0;
}
for (i = 0; i < err_len; i++)
erowerr[i] = 0;
for (i = 0; i < 32768; i++)
lookup[i] = -1;
for (i = 0; i < 256; i++)
{
range_tbl[i] = 0;
range_tbl[i + 256] = (unsigned char) i;
range_tbl[i + 512] = 255;
}
for (i = 0; i < 256; i++)
{
dith_max_tbl[i] = -DITHER_MAX;
dith_max_tbl[i + 256] = DITHER_MAX;
}
for (i = -DITHER_MAX; i <= DITHER_MAX; i++)
dith_max_tbl[i + 256] = (char)i;
for (i = 0 ; i < height; i++)
{
if (odd_scanline)
{
dir = -1;
in += (width - 1) * 3;
out += (width - 1);
thisrowerr = orowerr + 3;
nextrowerr = erowerr + width * 3;
}
else
{
dir = 1;
thisrowerr = erowerr + 3;
nextrowerr = orowerr + width * 3;
}
nextrowerr[0] = nextrowerr[1] = nextrowerr[2] = 0;
for (j = 0; j < width; j++)
{
#ifdef DITHER2
r_pix = range[(thisrowerr[0] >> 1) + in[0]];
g_pix = range[(thisrowerr[1] >> 1) + in[1]];
b_pix = range[(thisrowerr[2] >> 1) + in[2]];
#else
r_pix = range[((thisrowerr[0] + 8) >> 4) + in[0]];
g_pix = range[((thisrowerr[1] + 8) >> 4) + in[1]];
b_pix = range[((thisrowerr[2] + 8) >> 4) + in[2]];
#endif
offset = (r_pix&248) << 7 | (g_pix&248) << 2 | b_pix >> 3;
if (lookup[offset] < 0)
lookup[offset] = bestcolor(r_pix, g_pix, b_pix);
*out = (unsigned char)lookup[offset];
r_pix = dith_max[r_pix - palette[0][lookup[offset]]];
g_pix = dith_max[g_pix - palette[1][lookup[offset]]];
b_pix = dith_max[b_pix - palette[2][lookup[offset]]];
#ifdef DITHER2
nextrowerr[0 ] = (short)r_pix;
thisrowerr[0+3] += (short)r_pix;
nextrowerr[1 ] = (short)g_pix;
thisrowerr[1+3] += (short)g_pix;
nextrowerr[2 ] = (short)b_pix;
thisrowerr[2+3] += (short)b_pix;
#else
two_val = r_pix * 2;
nextrowerr[0-3] = r_pix;
r_pix += two_val;
nextrowerr[0+3] += r_pix;
r_pix += two_val;
nextrowerr[0 ] += r_pix;
r_pix += two_val;
thisrowerr[0+3] += r_pix;
two_val = g_pix * 2;
nextrowerr[1-3] = g_pix;
g_pix += two_val;
nextrowerr[1+3] += g_pix;
g_pix += two_val;
nextrowerr[1 ] += g_pix;
g_pix += two_val;
thisrowerr[1+3] += g_pix;
two_val = b_pix * 2;
nextrowerr[2-3] = b_pix;
b_pix += two_val;
nextrowerr[2+3] += b_pix;
b_pix += two_val;
nextrowerr[2 ] += b_pix;
b_pix += two_val;
thisrowerr[2+3] += b_pix;
#endif
thisrowerr += 3;
nextrowerr -= 3;
in += dir * 3;
out += dir;
}
if ((i % 2) == 1)
{
in += (width + 1) * 3;
out += (width + 1);
}
odd_scanline = !odd_scanline;
}
free(range_tbl);
free(lookup);
free(erowerr);
free(orowerr);
free(dith_max_tbl);
#else
long i = 0, j = 0;
long r_pix = 0, g_pix = 0, b_pix=0;
long r_err = 0, g_err = 0, b_err=0;
long offset = 0;
BYTE *range_tbl = (BYTE*)malloc(3 * 256), *range = range_tbl + 256;
short *lookup = (sshort *)malloc(sizeof(short) * 32768);
if (range_tbl == NULL || lookup == NULL)
{
if (range_tbl != NULL)
free(range_tbl);
if (lookup != NULL)
free(lookup);
return 0;
}
for (i = 0; i < 32768; i++)
lookup[i] = -1;
for (i = 0; i < 256; i++)
{
range_tbl[i] = 0;
range_tbl[i + 256] = (BYTE) i;
range_tbl[i + 512] = 255;
}
for (i = 0; i < height; i++)
{
r_err = g_err = b_err = 0;
for (j = width - 1; j >= 0; j--)
{
r_pix = range[(r_err >> 1) + in[0]];
g_pix = range[(g_err >> 1) + in[1]];
b_pix = range[(b_err >> 1) + in[2]];
offset = (r_pix&248) << 7 | (g_pix&248) << 2 | b_pix >> 3;
if (lookup[offset] < 0)
lookup[offset] = bestcolor(r_pix, g_pix, b_pix);
*out++ = (unsigned char)lookup[offset];
r_err = r_pix - palette[0][lookup[offset]];
g_err = g_pix - palette[1][lookup[offset]];
b_err = b_pix - palette[2][lookup[offset]];
in += 3;
}
}
free(range_tbl);
free(lookup);
#endif
}
return 1;
}
static int bestcolor(int r, int g, int b)
{
unsigned long i = 0, bestcolor = 0, curdist = 0, mindist = 0;
long rdist = 0, gdist = 0, bdist = 0;
r = (r & 248) + 4;
g = (g & 248) + 4;
b = (b & 248) + 4;
mindist = 200000;
for (i = 0; i < (unsigned long)tot_colors; i++)
{
rdist = palette[0][i] - r;
gdist = palette[1][i] - g;
bdist = palette[2][i] - b;
curdist = squares[rdist] + squares[gdist] + squares[bdist];
if (curdist < mindist)
{
mindist = curdist;
bestcolor = i;
}
}
return bestcolor;
}

View file

@ -1,6 +0,0 @@
#ifndef _QUANT_H_
#define _QUANT_H_
bool dl1quant(unsigned char *inbuf, unsigned char *outbuf, int width, int height, int quant_to, int dither, unsigned char userpal[3][256]);
#endif // _QUANT_H_

110
common/system.h Executable file → Normal file
View file

@ -1,9 +1,6 @@
#ifndef _SYSTEM_H_
#define _SYSTEM_H_
#include "typedefs.h"
#include "array.h"
// Assert macros.
#ifdef LC_DEBUG
@ -21,7 +18,7 @@ do \
#else
#define LC_ASSERT(expr, desc) do { } while(0)
#define LC_ASSERT(...) do { } while(0)
#define LC_ASSERT_FALSE(Desc) LC_ASSERT(0, Desc)
@ -30,101 +27,22 @@ do \
#if _MSC_VER >= 1600
#define LC_CASSERT(x) static_assert(x, "Assertion failed: " #x)
#else
#define LC_CASSERT_CONCAT1(e, l) extern int LC_CASSERT_##l[(int)(e) ? 1 : -1]
#define LC_CASSERT_CONCAT2(e, l) LC_CASSERT_CONCAT1(e, l)
#define LC_CASSERT(e) LC_CASSERT_CONCAT2(e, __LINE__)
#define LC_CASSERT_CONCAT(arg1, arg2) LC_CASSERT_CONCAT_(arg1, arg2)
#define LC_CASSERT_CONCAT_(arg1, arg2) arg1##arg2
#define LC_CASSERT(expression)\
struct LC_CASSERT_CONCAT(__assertion_at_line_, __LINE__) \
{ \
lcStaticAssert<static_cast<bool>((expression))> LC_CASSERT_CONCAT(LC_CASSERT_CONCAT(_ASSERTION_FAILED_AT_LINE_, __LINE__), _); \
}; \
typedef lcStaticAssertTest<sizeof(LC_CASSERT_CONCAT(__assertion_at_line_, __LINE__))> LC_CASSERT_CONCAT(__assertion_test_at_line_, __LINE__)
template<bool> struct lcStaticAssert;
template<> struct lcStaticAssert<true> { };
template<int i> struct lcStaticAssertTest { };
#endif
// Profile functions
bool Sys_ProfileSaveInt (const char *section, const char *key, int value);
bool Sys_ProfileSaveString (const char *section, const char *key, const char *value);
int Sys_ProfileLoadInt (const char *section, const char *key, int default_value);
char* Sys_ProfileLoadString (const char *section, const char *key, const char *default_value);
// Memory render
void* Sys_StartMemoryRender (int width, int height);
void Sys_FinishMemoryRender (void* param);
// FIXME: moved to basewnd, remove
// Message Box
#define LC_OK 1
#define LC_CANCEL 2
#define LC_ABORT 3
#define LC_RETRY 4
#define LC_IGNORE 5
#define LC_YES 6
#define LC_NO 7
#define LC_MB_OK 0x000
#define LC_MB_OKCANCEL 0x001
//#define LC_MB_ABORTRETRYIGNORE 0x002
#define LC_MB_YESNOCANCEL 0x003
#define LC_MB_YESNO 0x004
//#define LC_MB_RETRYCANCEL 0x005
#define LC_MB_ICONERROR 0x010
#define LC_MB_ICONQUESTION 0x020
#define LC_MB_ICONWARNING 0x030
#define LC_MB_ICONINFORMATION 0x040
#define LC_MB_TYPEMASK 0x00F
#define LC_MB_ICONMASK 0x0F0
int Sys_MessageBox (const char* text, const char* caption="LeoCAD", int type=LC_MB_OK|LC_MB_ICONINFORMATION);
// FIXME end
// Misc stuff
bool Sys_KeyDown (int key);
void Sys_GetFileList(const char* Path, ObjArray<String>& FileList);
class Camera;
class PieceInfo;
// User Interface
void SystemUpdateViewport(int nNew, int nOld);
void SystemUpdateAction(int nNew, int nOld);
void SystemUpdateColorList(int nNew);
void SystemUpdateRenderingMode(bool bFast);
void SystemUpdateUndoRedo(char* undo, char* redo);
void SystemUpdateSnap(const unsigned long nSnap);
void SystemUpdateCurrentCamera(Camera* pOld, Camera* pNew, const PtrArray<Camera>& Cameras);
void SystemUpdateCameraMenu(const PtrArray<Camera>& Cameras);
void SystemUpdateTime(bool bAnimation, int nTime, int nTotal);
void SystemUpdateAnimation(bool bAnimation, bool bAddKeys);
void SystemUpdateSnap(unsigned short MoveSnap, unsigned short RotateSnap);
void SystemUpdateSelected(unsigned long flags, int SelectedCount, class Object* Focus);
void SystemUpdatePaste(bool enable);
void SystemUpdatePlay(bool play, bool stop);
void SystemUpdateCategories(bool SearchOnly);
void SystemInit();
void SystemFinish();
int SystemDoMessageBox(const char* prompt, int nMode);
bool SystemDoDialog(int nMode, void* param);
void SystemDoPopupMenu(int nMenu, int x, int y);
void SystemDoWaitCursor(int nCode);
void SystemSetWindowCaption(char* caption);
void SystemPieceComboAdd(char* name);
void SystemCaptureMouse();
void SystemReleaseMouse();
void SystemExportClipboard(lcFile* clip);
lcFile* SystemImportClipboard();
void SystemPumpMessages();
long SystemGetTicks();
void SystemStartProgressBar(int nLower, int nUpper, int nStep, const char* Text);
void SytemEndProgressBar();
void SytemStepProgressBar();
#endif // _SYSTEM_H_

View file

@ -12,6 +12,7 @@
#include "camera.h"
#include "system.h"
#include "lc_texture.h"
#include "lc_profile.h"
/////////////////////////////////////////////////////////////////////////////
// Static functions
@ -809,7 +810,7 @@ void Terrain::FindVisiblePatches(Camera* pCam, float aspect)
void Terrain::LoadDefaults(bool bLinear)
{
unsigned long rgb = Sys_ProfileLoadInt ("Default", "Floor", RGB (0,191,0));
unsigned long rgb = lcGetProfileInt(LC_PROFILE_DEFAULT_FLOOR_COLOR);
m_fColor[0] = (float)((unsigned char) (rgb))/255;
m_fColor[1] = (float)((unsigned char) (((unsigned short) (rgb)) >> 8))/255;
m_fColor[2] = (float)((unsigned char) ((rgb) >> 16))/255;
@ -817,7 +818,7 @@ void Terrain::LoadDefaults(bool bLinear)
m_uSize = 50;
m_vSize = 50;
strcpy (m_strTexture, Sys_ProfileLoadString ("Default", "FloorBMP", ""));
strcpy(m_strTexture, lcGetProfileString(LC_PROFILE_DEFAULT_FLOOR_TEXTURE));
m_pTexture->Unload();
m_nOptions = LC_TERRAIN_FLAT;

View file

@ -3,6 +3,10 @@
class Camera;
#define LC_TERRAIN_FLAT 0x01 // Flat terrain
#define LC_TERRAIN_TEXTURE 0x02 // Use texture
#define LC_TERRAIN_SMOOTH 0x04 // Smooth shading
class TerrainPatch
{
public:

View file

@ -1,388 +0,0 @@
// Typedefs.
//
#ifndef _TYPEDEF_H_
#define _TYPEDEF_H_
class Group;
class Piece;
class PieceInfo;
class Camera;
#include "str.h"
#include "lc_math.h"
enum LC_NOTIFY
{
LC_COLOR_CHANGED,
LC_CAPTURE_LOST,
LC_ACTIVATE,
LC_PIECE_MODIFIED,
LC_CAMERA_MODIFIED,
LC_LIGHT_MODIFIED
};
enum LC_COMMANDS
{
LC_FILE_NEW,
LC_FILE_OPEN,
LC_FILE_MERGE,
LC_FILE_SAVE,
LC_FILE_SAVEAS,
LC_FILE_PICTURE,
LC_FILE_3DS,
LC_FILE_HTML,
LC_FILE_BRICKLINK,
LC_FILE_POVRAY,
LC_FILE_WAVEFRONT,
LC_FILE_PROPERTIES,
LC_FILE_TERRAIN,
LC_FILE_LIBRARY,
LC_FILE_RECENT,
LC_EDIT_UNDO,
LC_EDIT_REDO,
LC_EDIT_CUT,
LC_EDIT_COPY,
LC_EDIT_PASTE,
LC_EDIT_SELECT_ALL,
LC_EDIT_SELECT_NONE,
LC_EDIT_SELECT_INVERT,
LC_EDIT_SELECT_BYNAME,
LC_PIECE_INSERT,
LC_PIECE_DELETE,
LC_PIECE_MINIFIG,
LC_PIECE_ARRAY,
LC_PIECE_COPYKEYS,
LC_PIECE_GROUP,
LC_PIECE_UNGROUP,
LC_PIECE_GROUP_ADD,
LC_PIECE_GROUP_REMOVE,
LC_PIECE_GROUP_EDIT,
LC_PIECE_HIDE_SELECTED,
LC_PIECE_HIDE_UNSELECTED,
LC_PIECE_UNHIDE_ALL,
LC_PIECE_PREVIOUS,
LC_PIECE_NEXT,
LC_VIEW_PREFERENCES,
LC_VIEW_ZOOM,
LC_VIEW_ZOOMIN,
LC_VIEW_ZOOMOUT,
LC_VIEW_ZOOMEXTENTS,
LC_VIEW_STEP_NEXT,
LC_VIEW_STEP_PREVIOUS,
LC_VIEW_STEP_FIRST,
LC_VIEW_STEP_LAST,
LC_VIEW_STEP_CHOOSE,
LC_VIEW_STEP_SET,
LC_VIEW_STEP_INSERT,
LC_VIEW_STEP_DELETE,
LC_VIEW_STOP,
LC_VIEW_PLAY,
LC_VIEW_VIEWPOINT_FRONT,
LC_VIEW_VIEWPOINT_BACK,
LC_VIEW_VIEWPOINT_TOP,
LC_VIEW_VIEWPOINT_BOTTOM,
LC_VIEW_VIEWPOINT_LEFT,
LC_VIEW_VIEWPOINT_RIGHT,
LC_VIEW_VIEWPOINT_HOME,
LC_VIEW_CAMERA_MENU,
LC_VIEW_CAMERA_RESET,
LC_HELP_ABOUT,
LC_TOOLBAR_ANIMATION,
LC_TOOLBAR_ADDKEYS,
LC_TOOLBAR_SNAPMENU,
LC_TOOLBAR_LOCKMENU,
LC_TOOLBAR_FASTRENDER,
LC_EDIT_MOVEXY_SNAP_0,
LC_EDIT_MOVEXY_SNAP_1,
LC_EDIT_MOVEXY_SNAP_2,
LC_EDIT_MOVEXY_SNAP_3,
LC_EDIT_MOVEXY_SNAP_4,
LC_EDIT_MOVEXY_SNAP_5,
LC_EDIT_MOVEXY_SNAP_6,
LC_EDIT_MOVEXY_SNAP_7,
LC_EDIT_MOVEXY_SNAP_8,
LC_EDIT_MOVEXY_SNAP_9,
LC_EDIT_MOVEZ_SNAP_0,
LC_EDIT_MOVEZ_SNAP_1,
LC_EDIT_MOVEZ_SNAP_2,
LC_EDIT_MOVEZ_SNAP_3,
LC_EDIT_MOVEZ_SNAP_4,
LC_EDIT_MOVEZ_SNAP_5,
LC_EDIT_MOVEZ_SNAP_6,
LC_EDIT_MOVEZ_SNAP_7,
LC_EDIT_MOVEZ_SNAP_8,
LC_EDIT_MOVEZ_SNAP_9,
LC_EDIT_ANGLE_SNAP_0,
LC_EDIT_ANGLE_SNAP_1,
LC_EDIT_ANGLE_SNAP_2,
LC_EDIT_ANGLE_SNAP_3,
LC_EDIT_ANGLE_SNAP_4,
LC_EDIT_ANGLE_SNAP_5,
LC_EDIT_ANGLE_SNAP_6,
LC_EDIT_ANGLE_SNAP_7,
LC_EDIT_ANGLE_SNAP_8,
LC_EDIT_ANGLE_SNAP_9,
LC_EDIT_ACTION_SELECT,
LC_EDIT_ACTION_INSERT,
LC_EDIT_ACTION_LIGHT,
LC_EDIT_ACTION_SPOTLIGHT,
LC_EDIT_ACTION_CAMERA,
LC_EDIT_ACTION_MOVE,
LC_EDIT_ACTION_ROTATE,
LC_EDIT_ACTION_ERASER,
LC_EDIT_ACTION_PAINT,
LC_EDIT_ACTION_ZOOM,
LC_EDIT_ACTION_ZOOM_REGION,
LC_EDIT_ACTION_PAN,
LC_EDIT_ACTION_ROTATE_VIEW,
LC_EDIT_ACTION_ROLL,
};
enum LC_ACTIONS
{
LC_ACTION_SELECT,
LC_ACTION_INSERT,
LC_ACTION_LIGHT,
LC_ACTION_SPOTLIGHT,
LC_ACTION_CAMERA,
LC_ACTION_MOVE,
LC_ACTION_ROTATE,
LC_ACTION_ERASER,
LC_ACTION_PAINT,
LC_ACTION_ZOOM,
LC_ACTION_ZOOM_REGION,
LC_ACTION_PAN,
LC_ACTION_ROTATE_VIEW,
LC_ACTION_ROLL,
LC_ACTION_CURVE
};
// Select by Name dialog data
enum LC_SEL_DATA_TYPE
{
LC_SELDLG_PIECE,
LC_SELDLG_CAMERA,
LC_SELDLG_LIGHT,
LC_SELDLG_GROUP
};
struct LC_SEL_DATA
{
const char* name;
unsigned char type;
bool selected;
void* pointer;
};
struct LC_PIECE_MODIFY
{
Piece* piece;
lcVector3 Position;
lcVector3 Rotation;
char name[81];
int from;
int to;
bool hidden;
int color;
};
struct LC_CAMERA_MODIFY
{
Camera* camera;
lcVector3 Eye;
lcVector3 Target;
lcVector3 Up;
char name[81];
float fovy;
float znear;
float zfar;
bool hidden;
};
// Image
enum LC_IMAGE_FORMATS
{
LC_IMAGE_BMP,
LC_IMAGE_GIF,
LC_IMAGE_JPG,
LC_IMAGE_PNG,
LC_IMAGE_AVI
};
struct LC_IMAGE_OPTS
{
unsigned char quality;
bool interlaced;
bool transparent;
bool truecolor;
unsigned char background[3];
float pause;
unsigned int format;
};
struct LC_IMAGEDLG_OPTS
{
char filename[LC_MAXPATH];
unsigned short from;
unsigned short to;
bool multiple;
unsigned short width;
unsigned short height;
LC_IMAGE_OPTS imopts;
};
enum LC_DIALOGS
{
LC_DLG_FILE_OPEN_PROJECT,
LC_DLG_FILE_SAVE_PROJECT,
LC_DLG_FILE_MERGE_PROJECT,
LC_DLG_FILE_OPEN,
LC_DLG_FILE_SAVE,
LC_DLG_DIRECTORY_BROWSE,
LC_DLG_PICTURE_SAVE,
LC_DLG_BRICKLINK,
LC_DLG_HTML,
LC_DLG_POVRAY,
LC_DLG_WAVEFRONT,
LC_DLG_MINIFIG,
LC_DLG_ARRAY,
LC_DLG_PREFERENCES,
LC_DLG_PROPERTIES,
LC_DLG_TERRAIN,
LC_DLG_LIBRARY,
LC_DLG_SELECTBYNAME,
LC_DLG_STEPCHOOSE,
LC_DLG_EDITGROUPS,
LC_DLG_GROUP,
LC_DLG_EDITCATEGORY,
LC_DLG_ABOUT
};
enum LC_FILEOPENDLG_TYPES
{
LC_FILEOPENDLG_LCF
};
struct LC_FILEOPENDLG_OPTS
{
int type;
char path[LC_MAXPATH];
int numfiles;
char** filenames;
};
enum LC_FILESAVEDLG_TYPES
{
LC_FILESAVEDLG_LCF,
};
struct LC_FILESAVEDLG_OPTS
{
int type;
char path[LC_MAXPATH];
};
struct LC_DLG_DIRECTORY_BROWSE_OPTS
{
const char* Title;
char Path[LC_MAXPATH];
};
struct LC_POVRAYDLG_OPTS
{
bool render;
char povpath[LC_MAXPATH];
char outpath[LC_MAXPATH];
char libpath[LC_MAXPATH];
};
struct LC_HTMLDLG_OPTS
{
char path[LC_MAXPATH];
bool singlepage;
bool index;
bool images;
bool id;
int color;
bool listend;
bool liststep;
bool highlight;
LC_IMAGEDLG_OPTS imdlg;
};
struct LC_ARRAYDLG_OPTS
{
unsigned short n1DCount;
unsigned short n2DCount;
unsigned short n3DCount;
unsigned char nArrayDimension;
float f2D[3];
float f3D[3];
float fMove[3];
float fRotate[3];
};
struct LC_PROPERTIESDLG_OPTS
{
char strAuthor[101];
char strDescription[101];
char strComments[256];
char* strTitle;
char* strFilename;
const char** PieceNames;
int NumPieces;
int* PieceColorCount;
int NumColors;
};
struct LC_GROUPEDITDLG_OPTS
{
int piececount;
Piece** pieces;
Group** piecesgroups;
int groupcount;
Group** groups;
Group** groupsgroups;
};
struct LC_PREFERENCESDLG_OPTS
{
int nMouse;
int nSaveInterval;
char strUser[101];
char strPath[LC_MAXPATH];
unsigned long nDetail;
float fLineWidth;
int AASamples;
unsigned long nSnap;
unsigned short nAngleSnap;
unsigned short nGridSize;
unsigned long nScene;
float fDensity;
char strBackground[LC_MAXPATH];
float fBackground[4];
float fFog[4];
float fAmbient[4];
float fGrad1[3];
float fGrad2[3];
char strFooter[256];
char strHeader[256];
};
struct LC_CATEGORYDLG_OPTS
{
String Name;
String Keywords;
};
enum LC_TRANSFORM_TYPE
{
LC_TRANSFORM_ABSOLUTE_TRANSLATION,
LC_TRANSFORM_RELATIVE_TRANSLATION,
LC_TRANSFORM_ABSOLUTE_ROTATION,
LC_TRANSFORM_RELATIVE_ROTATION,
};
#endif

View file

@ -5,12 +5,16 @@
#include "view.h"
#include "system.h"
View::View(Project *pProject, GLWindow *share)
: GLWindow(share)
View::View(Project *project)
{
m_Project = pProject;
m_Project = project;
mCamera = NULL;
m_OverlayScale = 1.0f;
if (project->GetActiveView())
SetCamera(project->GetActiveView()->mCamera, false);
else
SetDefaultCamera();
}
View::~View()
@ -55,7 +59,7 @@ LC_CURSOR_TYPE View::GetCursor() const
switch (m_Project->GetAction())
{
case LC_ACTION_SELECT:
if (Sys_KeyDown(KEY_CONTROL))
if (mInputState.Control)
return LC_CURSOR_SELECT_GROUP;
else
return LC_CURSOR_SELECT;
@ -110,7 +114,6 @@ LC_CURSOR_TYPE View::GetCursor() const
case LC_ACTION_ROLL:
return LC_CURSOR_ROLL;
case LC_ACTION_CURVE:
default:
LC_ASSERT_FALSE("Unknown cursor type.");
return LC_CURSOR_DEFAULT;
@ -124,51 +127,55 @@ void View::OnDraw()
void View::OnInitialUpdate()
{
GLWindow::OnInitialUpdate();
m_Project->AddView(this);
}
void View::OnLeftButtonDown(int x, int y, bool Control, bool Shift)
void View::OnUpdateCursor()
{
m_Project->OnLeftButtonDown(this, x, y, Control, Shift);
SetCursor(GetCursor());
}
void View::OnLeftButtonUp(int x, int y, bool Control, bool Shift)
void View::OnLeftButtonDown()
{
m_Project->OnLeftButtonUp(this, x, y, Control, Shift);
m_Project->OnLeftButtonDown(this);
}
void View::OnLeftButtonDoubleClick(int x, int y, bool Control, bool Shift)
void View::OnLeftButtonUp()
{
m_Project->OnLeftButtonDoubleClick(this, x, y, Control, Shift);
m_Project->OnLeftButtonUp(this);
}
void View::OnMiddleButtonDown(int x, int y, bool Control, bool Shift)
void View::OnLeftButtonDoubleClick()
{
m_Project->OnMiddleButtonDown(this, x, y, Control, Shift);
m_Project->OnLeftButtonDoubleClick(this);
}
void View::OnMiddleButtonUp(int x, int y, bool Control, bool Shift)
void View::OnMiddleButtonDown()
{
m_Project->OnMiddleButtonUp(this, x, y, Control, Shift);
m_Project->OnMiddleButtonDown(this);
}
void View::OnRightButtonDown(int x, int y, bool Control, bool Shift)
void View::OnMiddleButtonUp()
{
m_Project->OnRightButtonDown(this, x, y, Control, Shift);
m_Project->OnMiddleButtonUp(this);
}
void View::OnRightButtonUp(int x, int y, bool Control, bool Shift)
void View::OnRightButtonDown()
{
m_Project->OnRightButtonUp(this, x, y, Control, Shift);
m_Project->OnRightButtonDown(this);
}
void View::OnMouseMove(int x, int y, bool Control, bool Shift)
void View::OnRightButtonUp()
{
m_Project->OnMouseMove(this, x, y, Control, Shift);
m_Project->OnRightButtonUp(this);
}
void View::OnMouseWheel(int x, int y, float Direction, bool Control, bool Shift)
void View::OnMouseMove()
{
m_Project->OnMouseWheel(this, x, y, Direction, Control, Shift);
m_Project->OnMouseMove(this);
}
void View::OnMouseWheel(float Direction)
{
m_Project->OnMouseWheel(this, Direction);
}

View file

@ -1,28 +1,29 @@
#ifndef _VIEW_H_
#define _VIEW_H_
#include "glwindow.h"
#include "lc_glwidget.h"
class Camera;
class Project;
class View : public GLWindow
class View : public lcGLWidget
{
public:
View(Project *pProject, GLWindow *share);
View(Project *project);
virtual ~View();
void OnDraw();
void OnInitialUpdate();
void OnLeftButtonDown(int x, int y, bool Control, bool Shift);
void OnLeftButtonUp(int x, int y, bool Control, bool Shift);
void OnLeftButtonDoubleClick(int x, int y, bool Control, bool Shift);
void OnMiddleButtonDown(int x, int y, bool Control, bool Shift);
void OnMiddleButtonUp(int x, int y, bool Control, bool Shift);
void OnRightButtonDown(int x, int y, bool Control, bool Shift);
void OnRightButtonUp(int x, int y, bool Control, bool Shift);
void OnMouseMove(int x, int y, bool Control, bool Shift);
void OnMouseWheel(int x, int y, float Direction, bool Control, bool Shift);
void OnUpdateCursor();
void OnLeftButtonDown();
void OnLeftButtonUp();
void OnLeftButtonDoubleClick();
void OnMiddleButtonDown();
void OnMiddleButtonUp();
void OnRightButtonDown();
void OnRightButtonUp();
void OnMouseMove();
void OnMouseWheel(float Direction);
void SetCamera(Camera* camera, bool ForceCopy);
void SetDefaultCamera();

15
docs/CREDITS.txt Normal file
View file

@ -0,0 +1,15 @@
The following people have contributed to LeoCAD:
Author, Original Design:
Leonardo Zide <leozide@gmail.com>
Contributions (in alphabetical order):
Christian Höltje <docwhat@gerf.org>
David Paleino <dapal@debian.org>
Joerg Scheurich <rusmufti@helpdesk.bera.rus.uni-stuttgart.de>
Nicolas Guilbert <nicolas@ange.dk>
Nicolas Schodet <nico-leocad@ni.fr.eu.org>
Pat Mahoney <pat7@gmx.net>
Petter Reinholdtsen <pere@hungry.com>
Renaud Breard <renaud@islande.net>
Torbjörn Söderstedt <torbjrn@gmail.com>

View file

@ -1,26 +0,0 @@
================
COMPILING LeoCAD
================
Linux/GNU platforms
-------------------
All your config options go into config.mk
You will need jpeglib. Install compile/install it and add it's header
directory as a -I to CPPFLAGS and -L to LDFLAGS. This isn't required if
it is installed to "standard" locations, like /usr/include and /usr/lib
Then just type MAKE
MS Windows
----------
- Extract LIBJPEG 6.0 to the win/libjpeg directory
- Extract ZLIB to win/zlib
- Extract LIBPNG to win/libpng
- Extract the 3DSFTK to win/3dsftk (use -d to keep directory names)
- Open VC++ and do a 'Make All'

View file

@ -1,89 +0,0 @@
LeoCAD for Linux
----------------
This is the only documentation you will find for the Linux
version, I'll start writing some help files in HTML format soon but
it's going to take a while (I really prefer to code and my english
is not perfect). I strongly advise you to follow the online tutorial
from my web page, it will at least get you started with the basic
editing commands.
I still have to finish some dialogs, the printing routines
and a few GUI items but all the rest should work fine. I'd also
like to warn you that this is my first Linux program so if you
find anything that doesn't behave as you expect, a bug or just
have some suggestions, feel free to email me at
leonardo@centroin.com.br
I hope you enjoy using LeoCAD as much as I enjoyed writing it,
Leonardo
HOW TO GET HELP
---------------
The best source of help is the LeoCAD mailing list at
leocad@gerf.org
You can subscribe/unsubscribe at
http://gerf.org/mailman/listinfo/leocad
INSTALLATION
------------
Instalation should be very simple for most systems, first you need
get the executable and the pieces library from my homepage (if you
already have the library for the MS Windows version, you don't
need to download it again).
Now you should unzip the files to a temporary directory (you
probably already did that) and move the file 'leocad' to
/usr/local/bin/ and the 4 files from the pieces library to
/usr/local/share/leocad/. If you wish to have the library files
installed in another place, set the environment variable LEOCAD_LIB
to that directory or start the program with the -l <path> option.
You need to have an OpenGL library, you can download Mesa 3D
from www.mesa3d.org if you don't have one already and you will also
need GTK+ 1.2, it's available from www.gtk.org
If you're using the precompiled version, then you will also need
libjpeg, zlib and libpng. If you're compiling from the sources, the
configuration utility will detect what libraries you have installed
and only support those file formats.
Current versions used are:
GTK+ 1.2 http://www.gtk.org/
MESA 3D 3.4 http://www.mesa3d.org/
LIBJPEG 6.0 ftp://ftp.uu.net/graphics/jpeg/
LIBPNG 1.0 http://www.libpng.org/pub/png/libpng.html
ZLIB 1.1 http://www.info-zip.org/pub/infozip/zlib/
COMMAND LINE OPTIONS
--------------------
The man (1) page has a more complete description of all command line
parameters available. This is just a list of the most used ones:
[filename]: Loads a file
-l <path>: Tells the program to use the piece library located in the directory
pointed by <path>
-i [filename]: Saves a picture and exit
-w <x>: Use this width for the picture
-h <y>: Use this height for the picture
Example:
leocad car.lcd -i car.gif -w 640 -h 480 -l /mnt/c/leocad/
This will start LeoCAD, load the file "car.lcd", create a GIF file
called "car.gif" with a resolution of 640 x 480 using the pieces
library in /mnt/c/leocad/ and exit when done.

213
leocad.pro Normal file
View file

@ -0,0 +1,213 @@
QT += core gui opengl network
TEMPLATE = app
greaterThan(QT_MAJOR_VERSION, 4) {
DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0
QT *= printsupport
}
INCLUDEPATH += qt common
CONFIG += precompile_header incremental
PRECOMPILED_HEADER = common/lc_global.h
win32 {
QMAKE_CXXFLAGS_WARN_ON += -wd4100
DEFINES += _CRT_SECURE_NO_WARNINGS _CRT_SECURE_NO_DEPRECATE=1 _CRT_NONSTDC_NO_WARNINGS=1
INCLUDEPATH += $$[QT_INSTALL_PREFIX]/src/3rdparty/zlib
QMAKE_LFLAGS += /INCREMENTAL
PRECOMPILED_SOURCE = common/lc_global.cpp
RC_FILE = qt/leocad.rc
} else {
LIBS += -lz
QMAKE_CXXFLAGS_WARN_ON += -Wno-unused-parameter
}
unix:!macx {
TARGET = leocad
} else {
TARGET = LeoCAD
}
release: DESTDIR = build/release
debug: DESTDIR = build/debug
OBJECTS_DIR = $$DESTDIR/.obj
MOC_DIR = $$DESTDIR/.moc
RCC_DIR = $$DESTDIR/.qrc
UI_DIR = $$DESTDIR/.ui
unix:!macx {
isEmpty(INSTALL_PREFIX):INSTALL_PREFIX = /usr
isEmpty(BIN_DIR):BIN_DIR = $$INSTALL_PREFIX/bin
isEmpty(DOCS_DIR):DOCS_DIR = $$INSTALL_PREFIX/share/doc/leocad
isEmpty(ICON_DIR):ICON_DIR = $$INSTALL_PREFIX/share/pixmaps
isEmpty(MAN_DIR):MAN_DIR = $$INSTALL_PREFIX/share/man/man1
isEmpty(DESKTOP_DIR):DESKTOP_DIR = $$INSTALL_PREFIX/share/applications
isEmpty(MIME_DIR):MIME_DIR = $$INSTALL_PREFIX/share/mime/packages
isEmpty(MIME_ICON_DIR):MIME_ICON_DIR = $$INSTALL_PREFIX/share/icons/hicolor/scalable/mimetypes
target.path = $$BIN_DIR
docs.path = $$DOCS_DIR
docs.files = docs/README.txt docs/CREDITS.txt docs/COPYING.txt
man.path = $$MAN_DIR
man.files = leocad.1
desktop.path = $$DESKTOP_DIR
desktop.files = qt/leocad.desktop
icon.path = $$ICON_DIR
icon.files = leocad.png
mime.path = $$MIME_DIR
mime.files = qt/leocad.xml
mime_icon.path = $$MIME_ICON_DIR
mime_icon.files = resources/application-vnd.leocad.svg
INSTALLS += target docs man desktop icon mime mime_icon
DEFINES += LC_INSTALL_PREFIX=\\\"$$INSTALL_PREFIX\\\"
}
macx {
ICON = resources/leocad.icns
QMAKE_INFO_PLIST = qt/Info.plist
library.files += library.bin
library.path = Contents/Resources
QMAKE_BUNDLE_DATA += library
}
SOURCES += common/view.cpp \
common/tr.cpp \
common/texfont.cpp \
common/terrain.cpp \
common/str.cpp \
common/project.cpp \
common/preview.cpp \
common/pieceinf.cpp \
common/piece.cpp \
common/opengl.cpp \
common/object.cpp \
common/minifig.cpp \
common/mainwnd.cpp \
common/light.cpp \
common/lc_zipfile.cpp \
common/lc_texture.cpp \
common/lc_mesh.cpp \
common/lc_library.cpp \
common/lc_file.cpp \
common/lc_colors.cpp \
common/lc_application.cpp \
common/image.cpp \
common/group.cpp \
common/debug.cpp \
common/curve.cpp \
common/console.cpp \
common/camera.cpp \
common/array.cpp \
common/lc_profile.cpp \
common/lc_category.cpp \
qt/lc_qmainwindow.cpp \
qt/system.cpp \
qt/qtmain.cpp \
qt/lc_qpovraydialog.cpp \
qt/lc_qarraydialog.cpp \
qt/lc_qgroupdialog.cpp \
qt/lc_qaboutdialog.cpp \
qt/lc_qpartstree.cpp \
qt/lc_qeditgroupsdialog.cpp \
qt/lc_qselectdialog.cpp \
qt/lc_qpropertiesdialog.cpp \
qt/lc_qhtmldialog.cpp \
qt/lc_qminifigdialog.cpp \
qt/lc_qpreferencesdialog.cpp \
qt/lc_qcategorydialog.cpp \
qt/lc_qprofile.cpp \
qt/lc_qimagedialog.cpp \
qt/lc_qapplication.cpp \
qt/lc_qupdatedialog.cpp \
qt/lc_qutils.cpp \
qt/lc_qpropertiestree.cpp \
qt/lc_qcolorpicker.cpp \
common/lc_commands.cpp \
common/lc_shortcuts.cpp \
qt/lc_qimage.cpp \
qt/lc_qglwidget.cpp \
qt/lc_qcolorlist.cpp \
qt/lc_qfinddialog.cpp
HEADERS += \
common/array.h \
common/view.h \
common/tr.h \
common/texfont.h \
common/terrain.h \
common/system.h \
common/str.h \
common/project.h \
common/preview.h \
common/pieceinf.h \
common/piece.h \
common/opengl.h \
common/object.h \
common/minifig.h \
common/mainwnd.h \
common/light.h \
common/lc_zipfile.h \
common/lc_texture.h \
common/lc_mesh.h \
common/lc_math.h \
common/lc_library.h \
common/lc_global.h \
common/lc_file.h \
common/lc_colors.h \
common/lc_application.h \
common/image.h \
common/group.h \
common/defines.h \
common/debug.h \
common/curve.h \
common/console.h \
common/camera.h \
common/basewnd.h \
common/lc_profile.h \
common/lc_category.h \
qt/lc_qmainwindow.h \
qt/lc_config.h \
qt/lc_qpovraydialog.h \
qt/lc_qarraydialog.h \
qt/lc_qgroupdialog.h \
qt/lc_qaboutdialog.h \
qt/lc_qpartstree.h \
qt/lc_qeditgroupsdialog.h \
qt/lc_qselectdialog.h \
qt/lc_qpropertiesdialog.h \
qt/lc_qhtmldialog.h \
qt/lc_qminifigdialog.h \
qt/lc_qpreferencesdialog.h \
qt/lc_qcategorydialog.h \
qt/lc_qimagedialog.h \
qt/lc_qupdatedialog.h \
qt/lc_qutils.h \
qt/lc_qpropertiestree.h \
qt/lc_qcolorpicker.h \
common/lc_commands.h \
common/lc_shortcuts.h \
qt/lc_qglwidget.h \
qt/lc_qcolorlist.h \
common/lc_glwidget.h \
qt/lc_qfinddialog.h
FORMS += \
qt/lc_qpovraydialog.ui \
qt/lc_qarraydialog.ui \
qt/lc_qgroupdialog.ui \
qt/lc_qaboutdialog.ui \
qt/lc_qeditgroupsdialog.ui \
qt/lc_qselectdialog.ui \
qt/lc_qpropertiesdialog.ui \
qt/lc_qhtmldialog.ui \
qt/lc_qminifigdialog.ui \
qt/lc_qpreferencesdialog.ui \
qt/lc_qcategorydialog.ui \
qt/lc_qimagedialog.ui \
qt/lc_qupdatedialog.ui \
qt/lc_qfinddialog.ui
OTHER_FILES +=
RESOURCES += leocad.qrc

66
leocad.qrc Normal file
View file

@ -0,0 +1,66 @@
<RCC>
<qresource prefix="/">
<file>resources/action_camera.png</file>
<file>resources/action_delete.png</file>
<file>resources/action_insert.png</file>
<file>resources/action_light.png</file>
<file>resources/action_move.png</file>
<file>resources/action_next.png</file>
<file>resources/action_paint.png</file>
<file>resources/action_pan.png</file>
<file>resources/action_previous.png</file>
<file>resources/action_roll.png</file>
<file>resources/action_rotate.png</file>
<file>resources/action_rotate_view.png</file>
<file>resources/action_select.png</file>
<file>resources/action_spotlight.png</file>
<file>resources/action_zoom.png</file>
<file>resources/action_zoom_extents.png</file>
<file>resources/action_zoom_region.png</file>
<file>resources/cursor_camera.png</file>
<file>resources/cursor_delete.png</file>
<file>resources/cursor_insert.png</file>
<file>resources/cursor_light.png</file>
<file>resources/cursor_move.png</file>
<file>resources/cursor_paint.png</file>
<file>resources/cursor_pan.png</file>
<file>resources/cursor_roll.png</file>
<file>resources/cursor_rotate.png</file>
<file>resources/cursor_rotatex.png</file>
<file>resources/cursor_rotatey.png</file>
<file>resources/cursor_rotate_view.png</file>
<file>resources/cursor_select.png</file>
<file>resources/cursor_select_multiple.png</file>
<file>resources/cursor_spotlight.png</file>
<file>resources/cursor_zoom.png</file>
<file>resources/cursor_zoom_region.png</file>
<file>resources/edit_copy.png</file>
<file>resources/edit_cut.png</file>
<file>resources/edit_lock.png</file>
<file>resources/edit_paste.png</file>
<file>resources/edit_redo.png</file>
<file>resources/edit_snap_angle.png</file>
<file>resources/edit_snap_move.png</file>
<file>resources/edit_transform.png</file>
<file>resources/edit_undo.png</file>
<file>resources/file_new.png</file>
<file>resources/file_open.png</file>
<file>resources/file_print.png</file>
<file>resources/file_print_preview.png</file>
<file>resources/file_save.png</file>
<file>resources/time_first.png</file>
<file>resources/time_last.png</file>
<file>resources/time_next.png</file>
<file>resources/time_pause.png</file>
<file>resources/time_play.png</file>
<file>resources/time_previous.png</file>
<file>resources/time_stop.png</file>
<file>resources/icon64.png</file>
<file>resources/help_email.png</file>
<file>resources/help_homepage.png</file>
<file>resources/view_zoomextents.png</file>
<file>resources/view_split_horizontal.png</file>
<file>resources/view_split_vertical.png</file>
<file>resources/file_picture.png</file>
</qresource>
</RCC>

View file

@ -1 +0,0 @@
include ../generic.mk

View file

@ -1,123 +0,0 @@
//
// BaseWnd class implementation for Linux
//
#include "lc_global.h"
#include <stdlib.h>
#include <gdk/gdkkeysyms.h>
#include "basewnd.h"
#include "dialogs.h"
#include "main.h"
BaseWnd::BaseWnd (BaseWnd *parent, int menu_count)
{
m_pMenuItems = new BaseMenuItem[menu_count];
memset(m_pMenuItems, 0, sizeof(BaseMenuItem[menu_count]));
m_pParent = parent;
m_pXID = gtk_window_new (GTK_WINDOW_TOPLEVEL);
if (parent != NULL)
gtk_window_set_transient_for (GTK_WINDOW (m_pXID), GTK_WINDOW (parent->GetXID ()));
}
BaseWnd::~BaseWnd ()
{
delete [] m_pMenuItems;
m_pMenuItems = NULL;
}
void BaseWnd::BeginWait ()
{
GdkCursor *cursor = gdk_cursor_new (GDK_WATCH);
gdk_window_set_cursor (m_pXID->window, cursor);
gdk_cursor_destroy (cursor);
}
void BaseWnd::EndWait ()
{
gdk_window_set_cursor (m_pXID->window, NULL);
}
int BaseWnd::MessageBox (const char* text, const char* caption, int flags)
{
return msgbox_execute (text, caption, flags);
}
void BaseWnd::ShowMenuItem (int id, bool show)
{
if (!m_pMenuItems[id].widget)
return;
if (show)
gtk_widget_show (m_pMenuItems[id].widget);
else
gtk_widget_hide (m_pMenuItems[id].widget);
}
void BaseWnd::EnableMenuItem (int id, bool enable)
{
if (!m_pMenuItems[id].widget)
return;
gtk_widget_set_sensitive (m_pMenuItems[id].widget, enable);
}
void BaseWnd::CheckMenuItem (int id, bool check)
{
if (!m_pMenuItems[id].widget)
return;
ignore_commands = true;
gtk_check_menu_item_set_state (GTK_CHECK_MENU_ITEM (m_pMenuItems[id].widget), check);
ignore_commands = false;
}
#include <stdio.h>
void BaseWnd::SetMenuItemText (int id, const char *text)
{
gboolean underscore;
gchar *r;
const char *p;
gchar *pattern;
gint length;
if (!m_pMenuItems[id].widget)
return;
length = strlen (text);
pattern = g_new (gchar, length+1);
underscore = FALSE;
p = text;
r = pattern;
while (*p)
{
if (underscore)
{
if (*p == '&')
*r++ = *p;
else
{
*r++ = '_';
*r++ = *p;
}
underscore = FALSE;
}
else
{
if (*p == '&')
underscore = TRUE;
else
*r++ = *p;
}
p++;
}
*r = 0;
gtk_label_set_text_with_mnemonic(GTK_LABEL(GTK_BIN(m_pMenuItems[id].widget)->child), pattern);
g_free (pattern);
}

File diff suppressed because it is too large Load diff

View file

@ -1,29 +0,0 @@
#ifndef _DIALOGS_H_
#define _DIALOGS_H_
// TODO: obsolete, delete
gint dialog_delete_callback(GtkWidget *widget, GdkEvent* event, gpointer data);
void modifydlg_toggle();
// All dialogs
int openprojectdlg_execute(char* filename);
int saveprojectdlg_execute(char* filename);
int savepicturedlg_execute(void* param);
int msgbox_execute(const char* text, const char *caption, int flags);
int arraydlg_execute(void* param);
int aboutdlg_execute(void* param);
int bricklinkdlg_execute(void* param);
int htmldlg_execute(void* param);
int imageoptsdlg_execute(GtkWidget* parent, void* param, bool from_htmldlg);
int povraydlg_execute(void* param);
int wavefrontdlg_execute(void* param);
int preferencesdlg_execute(void* param);
int propertiesdlg_execute(void* param);
int groupeditdlg_execute(void* param);
int groupdlg_execute(void* param);
int minifigdlg_execute(void* param);
int librarydlg_execute(void* param);
#endif // _DIALOGS_H_

View file

@ -1,296 +0,0 @@
#include "lc_global.h"
#include <gtk/gtk.h>
#include <unistd.h>
#include <string.h>
#include <stdlib.h>
#include "system.h"
#include "dialogs.h"
#include "lc_file.h"
#include "image.h"
#include "main.h"
// =============================================================================
// Open Project Dialog
static void openprojectdlg_preview(GtkFileChooser* dlg, GtkPreview* preview)
{
char *filename, *p = NULL;
bool loaded = false;
Image image;
filename = gtk_file_chooser_get_preview_filename(dlg);
if (filename)
p = strrchr(filename, '.');
if ((p != NULL) && (g_ascii_strcasecmp(p+1, "lcd") == 0))
{
float fv;
char id[32];
lcDiskFile file;
file.Open(filename, "rb");
file.ReadBuffer(id, 32);
sscanf(strchr(id, ' '), "%f", &fv);
if (fv > 0.4f)
{
file.ReadFloats(&fv, 1);
if (fv > 0.7f)
{
lcuint32 dwPosition;
file.Seek(-4, SEEK_END);
file.ReadU32(&dwPosition, 1);
file.Seek(dwPosition, SEEK_SET);
if (dwPosition != 0)
{
if (fv < 1.0f)
{
file.Seek(54, SEEK_CUR);
image.Allocate(120, 100, false);
file.ReadBuffer(image.GetData(), 36000);
for (int y = 0; y < 50; y++)
for (int x = 0; x < 120; x++)
{
unsigned char *from = image.GetData() + x*3 + y*360;
unsigned char *to = image.GetData() + x*3 + (100-y-1)*360;
unsigned char tmp[3] = { from[0], from[1], from[2] };
from[0] = to[2];
from[1] = to[1];
from[2] = to[0];
to[0] = tmp[2];
to[1] = tmp[1];
to[2] = tmp[0];
}
loaded = true;
}
else
{
loaded = image.FileLoad(file);
}
}
}
}
file.Close();
}
g_free(filename);
if (loaded == false)
{
GtkWidget *w = GTK_WIDGET(preview);
guchar row[360];
for (int x = 0; x < 120; x++)
{
row[x*3] = w->style->bg[0].red/0xFF;
row[x*3+1] = w->style->bg[0].green/0xFF;
row[x*3+2] = w->style->bg[0].blue/0xFF;
}
for (int y = 0; y < 100; y++)
gtk_preview_draw_row(preview, row, 0, y, 120);
gtk_widget_draw(w, NULL);
}
else
{
for (int y = 0; y < 100; y++)
gtk_preview_draw_row(preview, image.GetData()+y*360, 0, y, 120);
gtk_widget_draw(GTK_WIDGET(preview), NULL);
}
gtk_file_chooser_set_preview_widget_active(dlg, loaded);
}
int openprojectdlg_execute(char* filename)
{
GtkWidget* dlg;
int ret;
dlg = gtk_file_chooser_dialog_new("Open Project", GTK_WINDOW(((GtkWidget*)*main_window)), GTK_FILE_CHOOSER_ACTION_OPEN,
GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL, GTK_STOCK_OPEN, GTK_RESPONSE_OK, NULL);
gtk_file_chooser_set_filename(GTK_FILE_CHOOSER(dlg), filename);
GtkFileFilter* filter = gtk_file_filter_new();
gtk_file_filter_add_pattern(filter, "*.lcd");
gtk_file_filter_set_name(filter, "LeoCAD Files");
gtk_file_chooser_add_filter(GTK_FILE_CHOOSER(dlg), filter);
gtk_file_chooser_set_filter(GTK_FILE_CHOOSER(dlg), filter);
filter = gtk_file_filter_new();
gtk_file_filter_add_pattern(filter, "*.dat");
gtk_file_filter_add_pattern(filter, "*.ldr");
gtk_file_filter_set_name(filter, "LDraw Files");
gtk_file_chooser_add_filter(GTK_FILE_CHOOSER(dlg), filter);
filter = gtk_file_filter_new();
gtk_file_filter_add_pattern(filter, "*");
gtk_file_filter_set_name(filter, "All Files");
gtk_file_chooser_add_filter(GTK_FILE_CHOOSER(dlg), filter);
GtkWidget* preview = gtk_preview_new(GTK_PREVIEW_COLOR);
gtk_preview_size(GTK_PREVIEW(preview), 120, 100);
gtk_widget_show(preview);
gtk_file_chooser_set_preview_widget(GTK_FILE_CHOOSER(dlg), preview);
g_signal_connect(dlg, "update-preview", G_CALLBACK(openprojectdlg_preview), preview);
if (gtk_dialog_run(GTK_DIALOG(dlg)) == GTK_RESPONSE_OK)
{
char* dlgfilename = gtk_file_chooser_get_filename(GTK_FILE_CHOOSER(dlg));
strcpy(filename, dlgfilename);
g_free(dlgfilename);
ret = LC_OK;
}
else
ret = LC_CANCEL;
gtk_widget_destroy(dlg);
return ret;
}
// =============================================================================
// Save Project Dialog
int saveprojectdlg_execute(char* filename)
{
GtkWidget* dlg;
int ret;
dlg = gtk_file_chooser_dialog_new("Save Project", GTK_WINDOW(((GtkWidget*)*main_window)), GTK_FILE_CHOOSER_ACTION_SAVE,
GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL, GTK_STOCK_SAVE, GTK_RESPONSE_OK, NULL);
gtk_file_chooser_set_do_overwrite_confirmation(GTK_FILE_CHOOSER(dlg), TRUE);
gtk_file_chooser_set_filename(GTK_FILE_CHOOSER(dlg), filename);
GtkFileFilter* filter = gtk_file_filter_new();
gtk_file_filter_add_pattern(filter, "*.lcd");
gtk_file_filter_set_name(filter, "LeoCAD Files");
gtk_file_chooser_add_filter(GTK_FILE_CHOOSER(dlg), filter);
gtk_file_chooser_set_filter(GTK_FILE_CHOOSER(dlg), filter);
filter = gtk_file_filter_new();
gtk_file_filter_add_pattern(filter, "*.dat");
gtk_file_filter_add_pattern(filter, "*.ldr");
gtk_file_filter_set_name(filter, "LDraw Files");
gtk_file_chooser_add_filter(GTK_FILE_CHOOSER(dlg), filter);
filter = gtk_file_filter_new();
gtk_file_filter_add_pattern(filter, "*");
gtk_file_filter_set_name(filter, "All Files");
gtk_file_chooser_add_filter(GTK_FILE_CHOOSER(dlg), filter);
GtkWidget* check = gtk_check_button_new_with_label("Save Preview");
gtk_widget_show(check);
gtk_file_chooser_set_extra_widget(GTK_FILE_CHOOSER(dlg), check);
if (Sys_ProfileLoadInt("Default", "Save Preview", 0))
gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(check), TRUE);
if (gtk_dialog_run(GTK_DIALOG(dlg)) == GTK_RESPONSE_OK)
{
Sys_ProfileSaveInt("Default", "Save Preview", gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(check)));
char* dlgfilename = gtk_file_chooser_get_filename(GTK_FILE_CHOOSER(dlg));
strcpy(filename, dlgfilename);
g_free(dlgfilename);
ret = LC_OK;
}
else
ret = LC_CANCEL;
gtk_widget_destroy(dlg);
return ret;
}
// =============================================================================
// Save Picture Dialog
static void savepicturedlg_options(GtkWidget *widget, gpointer data)
{
imageoptsdlg_execute(gtk_widget_get_toplevel(widget), data, false);
}
int savepicturedlg_execute(void* param)
{
GtkWidget* dlg;
int ret;
dlg = gtk_file_chooser_dialog_new("Save Picture", GTK_WINDOW(((GtkWidget*)*main_window)), GTK_FILE_CHOOSER_ACTION_SAVE,
GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL, GTK_STOCK_SAVE, GTK_RESPONSE_OK, NULL);
gtk_file_chooser_set_do_overwrite_confirmation(GTK_FILE_CHOOSER(dlg), TRUE);
// gtk_file_chooser_set_filename(GTK_FILE_CHOOSER(dlg), filename);
GtkWidget* hbox = gtk_hbox_new(FALSE, 10);
gtk_widget_show(hbox);
gtk_file_chooser_set_extra_widget(GTK_FILE_CHOOSER(dlg), hbox);
GtkWidget* button = gtk_button_new_with_label ("Image Options");
gtk_widget_show(button);
// GTK_WIDGET_SET_FLAGS (button, GTK_CAN_DEFAULT);
gtk_signal_connect(GTK_OBJECT(button), "clicked", GTK_SIGNAL_FUNC(savepicturedlg_options), param);
gtk_box_pack_start(GTK_BOX(hbox), button, FALSE, FALSE, 0);
unsigned long image = Sys_ProfileLoadInt ("Default", "Image Options", 1|LC_IMAGE_TRANSPARENT);
LC_IMAGEDLG_OPTS* opts = (LC_IMAGEDLG_OPTS*)param;
opts->width = Sys_ProfileLoadInt ("Default", "Image Width", gdk_screen_width ());
opts->height = Sys_ProfileLoadInt ("Default", "Image Height", gdk_screen_height ());
opts->imopts.quality = Sys_ProfileLoadInt ("Default", "JPEG Quality", 70);
opts->imopts.interlaced = (image & LC_IMAGE_PROGRESSIVE) != 0;
opts->imopts.transparent = (image & LC_IMAGE_TRANSPARENT) != 0;
opts->imopts.truecolor = (image & LC_IMAGE_HIGHCOLOR) != 0;
opts->imopts.pause = (float)Sys_ProfileLoadInt ("Default", "AVI Pause", 100)/100;
opts->imopts.format = (unsigned char)(image & ~(LC_IMAGE_MASK));
if (gtk_dialog_run(GTK_DIALOG(dlg)) == GTK_RESPONSE_OK)
{
char* dlgfilename = gtk_file_chooser_get_filename(GTK_FILE_CHOOSER(dlg));
strcpy(opts->filename, dlgfilename);
g_free(dlgfilename);
char ext[5], *p;
if (strlen (opts->filename) == 0)
ret = LC_CANCEL;
p = strrchr(opts->filename, '.');
if (p != NULL)
{
strcpy (ext, p+1);
strlwr (ext);
}
else
ext[0] = '\0';
if ((strcmp (ext, "jpg") != 0) && (strcmp (ext, "jpeg") != 0) &&
(strcmp (ext, "bmp") != 0) && (strcmp (ext, "gif") != 0) &&
(strcmp (ext, "png") != 0) && (strcmp (ext, "avi") != 0))
{
switch (opts->imopts.format)
{
case LC_IMAGE_BMP: strcat(opts->filename, ".bmp"); break;
case LC_IMAGE_GIF: strcat(opts->filename, ".gif"); break;
case LC_IMAGE_JPG: strcat(opts->filename, ".jpg"); break;
case LC_IMAGE_PNG: strcat(opts->filename, ".png"); break;
case LC_IMAGE_AVI: strcat(opts->filename, ".avi"); break;
}
}
ret = LC_OK;
}
else
ret = LC_CANCEL;
gtk_widget_destroy(dlg);
return ret;
}

View file

@ -1,373 +0,0 @@
//
// This file holds all the dialogs that are called
// from the 'Pieces' submenu:
//
// - Group Name
// - Edit Groups
// - Minifig Wizard
//
#include "lc_global.h"
#include "lc_colors.h"
#include <gtk/gtk.h>
#include <gdk/gdkkeysyms.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include "opengl.h"
#include "gtktools.h"
#include "system.h"
#include "typedefs.h"
#include "globals.h"
#include "dialogs.h"
#include "pieceinf.h"
#include "main.h"
#include "minifig.h"
// =========================================================
// Minifig Wizard
struct LC_MINIFIGDLG_STRUCT
{
MinifigWizard* wizard;
GtkWidget *pieces[LC_MFW_NUMITEMS];
GtkWidget *colors[LC_MFW_NUMITEMS];
GtkWidget *angles[LC_MFW_NUMITEMS];
GtkWidget *preview;
GtkWidget *combo;
GtkWidget *dlg;
};
// A new color was selected from the menu
static void minifigdlg_color_response(GtkWidget *widget, gpointer data)
{
LC_MINIFIGDLG_STRUCT* info;
GtkWidget* button;
int i;
button = (GtkWidget*)gtk_object_get_data(GTK_OBJECT(widget), "button");
info = (LC_MINIFIGDLG_STRUCT*)gtk_object_get_data(GTK_OBJECT(button), "info");
if (!info)
return;
for (i = 0; i < 15; i++)
if (info->colors[i] == button)
break;
info->wizard->SetColor(i, GPOINTER_TO_INT(data));
info->wizard->Redraw();
set_button_pixmap2(button, gColorList[GPOINTER_TO_INT(data)].Value);
}
// A color button was clicked
static void minifigdlg_color_clicked(GtkWidget *widget, gpointer data)
{
int i;
GtkWidget *menu, *menuitem;
menu = gtk_menu_new();
for (i = 0; i < gNumUserColors; i++)
{
menuitem = gtk_menu_item_new_with_label(gColorList[i].Name);
gtk_widget_show(menuitem);
gtk_menu_append(GTK_MENU(menu), menuitem);
gtk_object_set_data(GTK_OBJECT(menuitem), "button", widget);
gtk_signal_connect(GTK_OBJECT(menuitem), "activate", GTK_SIGNAL_FUNC(minifigdlg_color_response), GINT_TO_POINTER(i));
}
gtk_menu_popup(GTK_MENU(menu), NULL, NULL, NULL, NULL, 0, 0);
}
// New piece was selected
static void minifigdlg_piece_changed(GtkWidget *widget, gpointer data)
{
LC_MINIFIGDLG_STRUCT* info;
int i, piece_type = -1, piece_index = -1;
const gchar* desc;
info = (LC_MINIFIGDLG_STRUCT*)gtk_object_get_data(GTK_OBJECT(widget), "info");
if (info == NULL)
return;
for (i = 0; i < LC_MFW_NUMITEMS; i++)
if (GTK_COMBO(info->pieces[i])->entry == widget)
{
piece_type = i;
break;
}
ObjArray<lcMinifigPieceInfo>& InfoArray = info->wizard->mSettings[piece_type];
desc = gtk_entry_get_text(GTK_ENTRY(widget));
for (i = 0; i < InfoArray.GetSize(); i++)
{
if (!strcmp(InfoArray[i].Description, desc))
{
piece_index = i;
break;
}
}
if (piece_index == -1 || piece_type == -1)
return;
info->wizard->SetSelectionIndex(piece_type, piece_index);
info->wizard->Redraw();
}
static void minifigdlg_updatecombo(LC_MINIFIGDLG_STRUCT* s)
{
char **names;
int count;
GList *lst = NULL;
s->wizard->GetMinifigNames(&names, &count);
for (int i = 0; i < count; i++)
lst = g_list_append(lst, names[i]);
if (lst == NULL)
lst = g_list_append(lst, (void*)"");
gtk_combo_set_popdown_strings(GTK_COMBO(s->combo), lst);
g_list_free(lst);
}
static void minifigdlg_updateselection(LC_MINIFIGDLG_STRUCT* s)
{
for (int i = 0; i < LC_MFW_NUMITEMS; i++)
{
int index = s->wizard->GetSelectionIndex(i);
GtkCombo* Combo = GTK_COMBO(s->pieces[i]);
gtk_signal_handler_block_by_func(GTK_OBJECT(Combo->entry), GTK_SIGNAL_FUNC(minifigdlg_piece_changed), NULL);
gtk_entry_set_text(GTK_ENTRY(Combo->entry), s->wizard->mSettings[i][index].Description);
gtk_list_select_item(GTK_LIST(Combo->list), index);
gtk_signal_handler_unblock_by_func(GTK_OBJECT(Combo->entry), GTK_SIGNAL_FUNC(minifigdlg_piece_changed), NULL);
}
}
static void minifigdlg_load(GtkWidget *widget, gpointer data)
{
LC_MINIFIGDLG_STRUCT* s = (LC_MINIFIGDLG_STRUCT*)data;
if (s->wizard->LoadMinifig(gtk_entry_get_text(GTK_ENTRY(GTK_COMBO(s->combo)->entry))) == false)
return;
for (int i = 0; i < LC_MFW_NUMITEMS; i++)
{
set_button_pixmap2(s->colors[i], gColorList[s->wizard->m_Colors[i]].Value);
if (s->angles[i] != NULL)
gtk_spin_button_set_value(GTK_SPIN_BUTTON(s->angles[i]), s->wizard->m_Angles[i]);
}
minifigdlg_updateselection(s);
s->wizard->Redraw();
}
static void minifigdlg_save(GtkWidget *widget, gpointer data)
{
LC_MINIFIGDLG_STRUCT* s = (LC_MINIFIGDLG_STRUCT*)data;
s->wizard->SaveMinifig(gtk_entry_get_text(GTK_ENTRY(GTK_COMBO(s->combo)->entry)));
minifigdlg_updatecombo(s);
}
static void minifigdlg_delete(GtkWidget *widget, gpointer data)
{
LC_MINIFIGDLG_STRUCT* s = (LC_MINIFIGDLG_STRUCT*)data;
s->wizard->DeleteMinifig(gtk_entry_get_text(GTK_ENTRY(GTK_COMBO(s->combo)->entry)));
minifigdlg_updatecombo(s);
}
static void adj_changed(GtkAdjustment *adj, gpointer data)
{
LC_MINIFIGDLG_STRUCT* info = (LC_MINIFIGDLG_STRUCT*)data;
float val;
int i;
for (i = 0; i < LC_MFW_NUMITEMS; i++)
if (info->angles[i] != NULL)
if (gtk_spin_button_get_adjustment(GTK_SPIN_BUTTON(info->angles[i])) == adj)
break;
if (i == LC_MFW_NUMITEMS)
return;
val = gtk_spin_button_get_value_as_float(GTK_SPIN_BUTTON(info->angles[i]));
if (val == info->wizard->m_Angles[i])
return;
info->wizard->SetAngle(i, val);
if (info->preview != NULL)
info->wizard->Redraw();
}
// Create a combo box with a color selection control
static void minifigdlg_createpair(LC_MINIFIGDLG_STRUCT* info, int idx, int num, GtkWidget* table)
{
GtkWidget *combo, *color, *spin;
GtkObject *adj;
combo = info->pieces[num] = gtk_combo_new();
gtk_widget_show(combo);
gtk_table_attach(GTK_TABLE(table), combo, 0, 1, idx, idx+1,
(GtkAttachOptions) (GTK_EXPAND | GTK_FILL), (GtkAttachOptions) GTK_EXPAND, 0, 0);
gtk_entry_set_editable(GTK_ENTRY(GTK_COMBO(combo)->entry), FALSE);
gtk_signal_connect(GTK_OBJECT(GTK_COMBO(combo)->entry), "changed", GTK_SIGNAL_FUNC(minifigdlg_piece_changed), NULL);
gtk_object_set_data(GTK_OBJECT(GTK_COMBO(combo)->entry), "info", info);
color = info->colors[num] = gtk_button_new_with_label("");
gtk_widget_set_events(color, GDK_EXPOSURE_MASK);
gtk_widget_show(color);
gtk_object_set_data(GTK_OBJECT(color), "color", &info->wizard->m_Colors[num]);
gtk_object_set_data(GTK_OBJECT(color), "info", info);
gtk_widget_set_usize(color, 40, 25);
gtk_signal_connect(GTK_OBJECT(color), "clicked", GTK_SIGNAL_FUNC(minifigdlg_color_clicked), info);
gtk_table_attach(GTK_TABLE(table), color, 1, 2, idx, idx+1, (GtkAttachOptions) GTK_FILL, (GtkAttachOptions) GTK_EXPAND, 0, 0);
if ((num == LC_MFW_BODY) || (num == LC_MFW_BODY2) || (num == LC_MFW_BODY3))
{
info->angles[num] = NULL;
return;
}
adj = gtk_adjustment_new(0, -180, 180, 1, 10, 0);
gtk_signal_connect(adj, "value_changed", GTK_SIGNAL_FUNC(adj_changed), info);
spin = info->angles[num] = gtk_spin_button_new(GTK_ADJUSTMENT(adj), 1, 0);
gtk_widget_show(spin);
gtk_object_set_data(GTK_OBJECT(color), "info", info);
gtk_table_attach(GTK_TABLE(table), spin, 2, 3, idx, idx+1, (GtkAttachOptions) GTK_FILL, (GtkAttachOptions) GTK_EXPAND, 0, 0);
gtk_spin_button_set_wrap(GTK_SPIN_BUTTON(spin), TRUE);
gtk_spin_button_set_numeric(GTK_SPIN_BUTTON(spin), TRUE);
gtk_entry_set_width_chars(GTK_ENTRY(spin), 4);
}
int minifigdlg_execute(void* param)
{
GtkWidget *vbox, *hbox, *frame, *table;
GtkWidget *dlg, *button;
LC_MINIFIGDLG_STRUCT s;
int i;
int ret;
memset(&s, 0, sizeof(s));
s.wizard = (MinifigWizard*)param;
dlg = gtk_dialog_new_with_buttons("Minifig Wizard", GTK_WINDOW(((GtkWidget*)(*main_window))),
(GtkDialogFlags)(GTK_DIALOG_MODAL | GTK_DIALOG_DESTROY_WITH_PARENT),
GTK_STOCK_OK, GTK_RESPONSE_OK, GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL, NULL);
gtk_container_set_border_width(GTK_CONTAINER(dlg), 5);
gtk_widget_realize(dlg);
s.dlg = dlg;
vbox = GTK_DIALOG(dlg)->vbox;
gtk_box_set_spacing(GTK_BOX(vbox), 10);
hbox = gtk_hbox_new(FALSE, 5);
gtk_widget_show(hbox);
gtk_box_pack_start(GTK_BOX(vbox), hbox, TRUE, TRUE, 0);
table = gtk_table_new(9, 3, FALSE);
gtk_widget_show(table);
gtk_box_pack_start(GTK_BOX(hbox), table, TRUE, TRUE, 0);
gtk_table_set_col_spacings(GTK_TABLE(table), 5);
gtk_table_set_row_spacings(GTK_TABLE(table), 5);
minifigdlg_createpair(&s, 0, LC_MFW_HATS, table);
minifigdlg_createpair(&s, 1, LC_MFW_HATS2, table);
minifigdlg_createpair(&s, 2, LC_MFW_NECK, table);
minifigdlg_createpair(&s, 3, LC_MFW_LARM, table);
minifigdlg_createpair(&s, 4, LC_MFW_LHAND, table);
minifigdlg_createpair(&s, 5, LC_MFW_LHANDA, table);
minifigdlg_createpair(&s, 6, LC_MFW_BODY2, table);
minifigdlg_createpair(&s, 7, LC_MFW_LLEG, table);
minifigdlg_createpair(&s, 8, LC_MFW_LLEGA, table);
s.wizard->CreateFromWindow(&s.preview);
frame = gtk_frame_new(NULL);
gtk_widget_show(frame);
gtk_container_add(GTK_CONTAINER(hbox), frame);
gtk_frame_set_shadow_type(GTK_FRAME(frame), GTK_SHADOW_IN);
gtk_widget_set_usize(GTK_WIDGET(s.preview), 150, 300);
gtk_container_add(GTK_CONTAINER(frame), GTK_WIDGET(s.preview));
gtk_widget_show(GTK_WIDGET(s.preview));
gtk_object_set_data(GTK_OBJECT(s.preview), "minifig", &s);
table = gtk_table_new(8, 3, FALSE);
gtk_widget_show(table);
gtk_box_pack_start(GTK_BOX(hbox), table, TRUE, TRUE, 0);
gtk_table_set_col_spacings(GTK_TABLE(table), 5);
gtk_table_set_row_spacings(GTK_TABLE(table), 5);
minifigdlg_createpair(&s, 0, LC_MFW_HEAD, table);
minifigdlg_createpair(&s, 1, LC_MFW_BODY, table);
minifigdlg_createpair(&s, 2, LC_MFW_RARM, table);
minifigdlg_createpair(&s, 3, LC_MFW_RHAND, table);
minifigdlg_createpair(&s, 4, LC_MFW_RHANDA, table);
minifigdlg_createpair(&s, 5, LC_MFW_BODY3, table);
minifigdlg_createpair(&s, 6, LC_MFW_RLEG, table);
minifigdlg_createpair(&s, 7, LC_MFW_RLEGA, table);
hbox = gtk_hbox_new(FALSE, 10);
gtk_widget_show(hbox);
gtk_box_pack_start(GTK_BOX(vbox), hbox, FALSE, TRUE, 0);
gtk_container_set_border_width(GTK_CONTAINER(hbox), 5);
s.combo = gtk_combo_new();
gtk_widget_show(s.combo);
gtk_box_pack_start(GTK_BOX(hbox), s.combo, FALSE, TRUE, 0);
gtk_signal_connect(GTK_OBJECT(GTK_COMBO(s.combo)->entry), "changed", GTK_SIGNAL_FUNC(minifigdlg_load), &s);
button = gtk_button_new_with_label("Save");
gtk_signal_connect(GTK_OBJECT(button), "clicked", GTK_SIGNAL_FUNC(minifigdlg_save), &s);
gtk_widget_show(button);
gtk_box_pack_start(GTK_BOX(hbox), button, FALSE, TRUE, 0);
button = gtk_button_new_with_label("Delete");
gtk_signal_connect(GTK_OBJECT(button), "clicked", GTK_SIGNAL_FUNC(minifigdlg_delete), &s);
gtk_widget_show(button);
gtk_box_pack_start(GTK_BOX(hbox), button, FALSE, TRUE, 0);
// Fill the combo boxes with the available pieces
for (i = 0; i < LC_MFW_NUMITEMS; i++)
{
GList* names = NULL;
int count = s.wizard->mSettings[i].GetSize();
for (int j = 0; j < count; j++)
names = g_list_append(names, s.wizard->mSettings[i][j].Description);
if (names != NULL)
{
gtk_signal_handler_block_by_func(GTK_OBJECT(GTK_COMBO(s.pieces[i])->entry), GTK_SIGNAL_FUNC(minifigdlg_piece_changed), NULL);
gtk_combo_set_popdown_strings(GTK_COMBO(s.pieces[i]), names);
g_list_free(names);
gtk_signal_handler_unblock_by_func(GTK_OBJECT(GTK_COMBO(s.pieces[i])->entry), GTK_SIGNAL_FUNC(minifigdlg_piece_changed), NULL);
}
}
gtk_widget_show(dlg);
minifigdlg_updatecombo(&s);
minifigdlg_updateselection(&s);
for (i = 0; i < LC_MFW_NUMITEMS; i++)
set_button_pixmap2(s.colors[i], gColorList[s.wizard->m_Colors[i]].Value);
if (gtk_dialog_run(GTK_DIALOG(dlg)) == GTK_RESPONSE_OK)
{
ret = LC_OK;
}
else
ret = LC_CANCEL;
gtk_widget_destroy(dlg);
return ret;
}

View file

@ -1,527 +0,0 @@
#include <stdio.h>
#include <gtk/gtk.h>
#include <gdk/gdkx.h>
#include "lc_global.h"
#include "lc_application.h"
#include "opengl.h"
#include "glwindow.h"
#include "defines.h"
#include "main.h"
#include "project.h"
#include "system.h"
struct GLWindowPrivate
{
GtkWidget *widget;
LC_CURSOR_TYPE Cursor;
};
static Display* WindowDisplay = NULL;
static GdkVisual* WindowGdkVisual = NULL;
static XVisualInfo* WindowXVisualInfo = NULL;
static bool WindowMultisample = false;
static GLXContext WindowContext;
static int WindowContextCount;
static bool dragging;
// =============================================================================
// static functions
static gint realize_event(GtkWidget *widget, gpointer data)
{
GLWindow *wnd = (GLWindow*)data;
wnd->MakeCurrent();
wnd->OnInitialUpdate();
return TRUE;
}
static gint expose_event(GtkWidget *widget, GdkEventExpose *event, gpointer data)
{
GLWindow *wnd = (GLWindow*)data;
GLWindowPrivate *prv = (GLWindowPrivate*)wnd->GetData();
if (event->count > 0)
return TRUE;
wnd->MakeCurrent();
wnd->OnDraw();
if (WindowContext)
pfnglXSwapBuffers(GDK_WINDOW_XDISPLAY(prv->widget->window), GDK_WINDOW_XWINDOW(prv->widget->window));
return TRUE;
}
static gint button_press_event(GtkWidget *widget, GdkEventButton *event, gpointer data)
{
GLWindow *wnd = (GLWindow*)data;
int x, y;
x = (int)event->x;
y = widget->allocation.height - (int)event->y - 1;
if (event->type == GDK_BUTTON_PRESS)
{
if (event->button == 1)
wnd->OnLeftButtonDown(x, y, (event->state & GDK_CONTROL_MASK) != 0, (event->state & GDK_SHIFT_MASK) != 0);
else if (event->button == 2)
wnd->OnMiddleButtonDown(x, y, (event->state & GDK_CONTROL_MASK) != 0, (event->state & GDK_SHIFT_MASK) != 0);
else if (event->button == 3)
wnd->OnRightButtonDown(x, y, (event->state & GDK_CONTROL_MASK) != 0, (event->state & GDK_SHIFT_MASK) != 0);
}
else if (event->type == GDK_2BUTTON_PRESS)
{
wnd->OnLeftButtonDoubleClick(x, y, (event->state & GDK_CONTROL_MASK) != 0, (event->state & GDK_SHIFT_MASK) != 0);
}
gtk_window_set_focus(GTK_WINDOW(gtk_widget_get_toplevel(widget)), widget);
gdk_pointer_grab(widget->window, FALSE, (GdkEventMask)(GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK | GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK),
NULL, NULL, GDK_CURRENT_TIME);
return TRUE;
}
static gint button_release_event(GtkWidget *widget, GdkEventButton *event, gpointer data)
{
GLWindow *wnd = (GLWindow*)data;
int x, y;
x = (int)event->x;
y = widget->allocation.height - (int)event->y - 1;
gdk_pointer_ungrab(GDK_CURRENT_TIME);
if (event->button == 1)
wnd->OnLeftButtonUp(x, y, (event->state & GDK_CONTROL_MASK) != 0, (event->state & GDK_SHIFT_MASK) != 0);
else if (event->button == 2)
wnd->OnMiddleButtonUp(x, y, (event->state & GDK_CONTROL_MASK) != 0, (event->state & GDK_SHIFT_MASK) != 0);
else if (event->button == 3)
wnd->OnRightButtonUp(x, y, (event->state & GDK_CONTROL_MASK) != 0, (event->state & GDK_SHIFT_MASK) != 0);
return TRUE;
}
static gint pointer_motion_event(GtkWidget *widget, GdkEventMotion *event, gpointer data)
{
GLWindow *wnd = (GLWindow*)data;
GdkModifierType state;
int x, y;
if (event->is_hint)
{
gdk_window_get_pointer(event->window, &x, &y, &state);
state = (GdkModifierType)0;
}
else
{
x = (int)event->x;
y = (int)event->y;
state = (GdkModifierType)event->state;
}
y = widget->allocation.height - y - 1;
wnd->OnMouseMove(x, y, (event->state & GDK_CONTROL_MASK) != 0, (event->state & GDK_SHIFT_MASK) != 0);
return TRUE;
}
static gboolean drag_drop(GtkWidget *widget, GdkDragContext *context, gint x, gint y, guint time, gpointer data)
{
if (!dragged_piece)
{
return FALSE;
}
GLWindow *wnd = (GLWindow*)data;
y = widget->allocation.height - y - 1;
lcGetActiveProject()->BeginPieceDrop(dragged_piece);
wnd->OnLeftButtonUp(x, y, FALSE, FALSE);
gtk_drag_finish(context, TRUE, FALSE, time);
return TRUE;
}
static void drag_leave(GtkWidget *widget, GdkDragContext *context, guint time, gpointer data)
{
if (dragging)
{
dragging = false;
lcGetActiveProject()->HandleNotify(LC_CAPTURE_LOST, 0);
}
}
static gboolean drag_motion(GtkWidget *widget, GdkDragContext *context, gint x, gint y, guint time, gpointer data)
{
if (!dragged_piece)
{
return FALSE;
}
GLWindow *wnd = (GLWindow*)data;
y = widget->allocation.height - y - 1;
if (!dragging)
{
dragging = true;
lcGetActiveProject()->BeginPieceDrop(dragged_piece);
}
wnd->OnMouseMove(x, y, FALSE, FALSE);
gdk_drag_status(context, GDK_ACTION_COPY, time);
return TRUE;
}
static gboolean scroll_event(GtkWidget *widget, GdkEventScroll *event, gpointer data)
{
GLWindow *wnd = (GLWindow*)data;
float Direction;
int x, y;
switch (event->direction)
{
case GDK_SCROLL_UP:
Direction = 1.0f;
break;
case GDK_SCROLL_DOWN:
Direction = -1.0f;
break;
default:
return FALSE;
}
x = (int)event->x;
y = widget->allocation.height - (int)event->y - 1;
wnd->OnMouseWheel(x, y, Direction, (event->state & GDK_CONTROL_MASK) != 0, (event->state & GDK_SHIFT_MASK) != 0);
return TRUE;
}
static gint size_allocate_event(GtkWidget *widget, GtkAllocation *allocation, gpointer data)
{
GLWindow *wnd = (GLWindow*)data;
wnd->OnSize(allocation->width, allocation->height);
return TRUE;
}
/*
static void destroy_event(GtkWidget *widget, gpointer data)
{
GLWindow *wnd = (GLWindow*)data;
wnd->DestroyContext();
}
*/
void GL_InitializeExtensions()
{
}
// =============================================================================
// GLWindow class
GLWindow::GLWindow(GLWindow *share)
{
m_pShare = share;
m_pData = g_malloc(sizeof(GLWindowPrivate));
memset(m_pData, 0, sizeof(GLWindowPrivate));
}
GLWindow::~GLWindow()
{
DestroyContext();
g_free(m_pData);
}
bool GLWindow::CreateFromWindow(void *data)
{
GLWindowPrivate *prv = (GLWindowPrivate*)m_pData;
if (WindowContext)
WindowContextCount++;
else
{
int attrlist[] = { GLX_RGBA, GLX_DOUBLEBUFFER, GLX_DEPTH_SIZE, 16, 0 };
WindowDisplay = GDK_DISPLAY();
if (!WindowDisplay)
{
printf("OpenGL fatal error: Cannot get display.\n");
return false;
}
WindowGdkVisual = gdk_visual_get_system();
if (WindowGdkVisual->depth < 16)
printf("OpenGL fatal error: LeoCAD needs a display with at least 16 bit colors.\n");
int AASamples = Sys_ProfileLoadInt("Default", "AASamples", 1);
if (AASamples > 1)
{
int attrlistAA[] = { GLX_RGBA, GLX_DOUBLEBUFFER, GLX_DEPTH_SIZE, 16, GLX_SAMPLE_BUFFERS_ARB, 1, GLX_SAMPLES_ARB, AASamples, 0 };
WindowXVisualInfo = pfnglXChooseVisual(WindowDisplay, DefaultScreen(WindowDisplay), attrlistAA);
if (WindowXVisualInfo)
WindowMultisample = true;
else
printf("OpenGL error: Could not find multisample visual.\n");
}
if (!WindowXVisualInfo)
{
WindowXVisualInfo = pfnglXChooseVisual(WindowDisplay, DefaultScreen(WindowDisplay), attrlist);
if (!WindowXVisualInfo)
{
printf("OpenGL fatal error: glXChooseVisual failed.\n");
return false;
}
}
WindowGdkVisual = gdkx_visual_get(WindowXVisualInfo->visualid);
if (WindowGdkVisual == NULL)
{
printf("OpenGL fatal error: Cannot get visual.\n");
return false;
}
WindowContext = pfnglXCreateContext(WindowDisplay, WindowXVisualInfo, NULL, True);
if (!WindowContext)
{
printf("OpenGL fatal error: Cannot create context.\n");
return false;
}
WindowContextCount = 1;
}
gtk_widget_push_colormap(gdk_colormap_new(WindowGdkVisual, TRUE));
gtk_widget_push_visual(WindowGdkVisual);
prv->widget = gtk_drawing_area_new();
gtk_widget_set_double_buffered(GTK_WIDGET(prv->widget), FALSE);
gtk_widget_pop_visual();
gtk_widget_pop_colormap();
GTK_WIDGET_SET_FLAGS(prv->widget, GTK_CAN_FOCUS);
gtk_widget_set_events(GTK_WIDGET(prv->widget), GDK_EXPOSURE_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK | GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK);
gtk_drag_dest_set(prv->widget, GTK_DEST_DEFAULT_MOTION, drag_target_list, 1, GDK_ACTION_COPY);
// Connect signal handlers
gtk_signal_connect(GTK_OBJECT(prv->widget), "expose_event", GTK_SIGNAL_FUNC(expose_event), this);
// gtk_signal_connect(GTK_OBJECT(prv->widget), "destroy", GTK_SIGNAL_FUNC(destroy_event), this);
gtk_signal_connect(GTK_OBJECT(prv->widget), "size_allocate", GTK_SIGNAL_FUNC(size_allocate_event), this);
gtk_signal_connect(GTK_OBJECT(prv->widget), "motion_notify_event", GTK_SIGNAL_FUNC(pointer_motion_event), this);
gtk_signal_connect(GTK_OBJECT(prv->widget), "button_press_event", GTK_SIGNAL_FUNC(button_press_event), this);
gtk_signal_connect(GTK_OBJECT(prv->widget), "button_release_event", GTK_SIGNAL_FUNC(button_release_event), this);
gtk_signal_connect(GTK_OBJECT(prv->widget), "drag_drop", GTK_SIGNAL_FUNC(drag_drop), this);
gtk_signal_connect(GTK_OBJECT(prv->widget), "drag_leave", GTK_SIGNAL_FUNC(drag_leave), this);
gtk_signal_connect(GTK_OBJECT(prv->widget), "drag_motion", GTK_SIGNAL_FUNC(drag_motion), this);
gtk_signal_connect(GTK_OBJECT(prv->widget), "scroll_event", GTK_SIGNAL_FUNC(scroll_event), this);
gtk_signal_connect(GTK_OBJECT(prv->widget), "realize", GTK_SIGNAL_FUNC(realize_event), this);
*((GtkWidget**)data) = prv->widget;
return true;
}
void GLWindow::DestroyContext()
{
if (!WindowContext)
return;
WindowContextCount--;
if (WindowContextCount)
return;
if (WindowContext == pfnglXGetCurrentContext())
pfnglXMakeCurrent(WindowDisplay, None, NULL);
pfnglXDestroyContext(WindowDisplay, WindowContext);
WindowContext = NULL;
XFree(WindowXVisualInfo);
WindowXVisualInfo = NULL;
}
void GLWindow::OnInitialUpdate()
{
MakeCurrent();
GL_InitializeSharedExtensions();
// GL_InitializeExtensions();
if (WindowMultisample)
glEnable(GL_MULTISAMPLE_ARB);
}
bool GLWindow::MakeCurrent()
{
GLWindowPrivate *prv = (GLWindowPrivate*)m_pData;
if (!WindowContext)
return false;
return pfnglXMakeCurrent(WindowDisplay, GDK_WINDOW_XWINDOW(prv->widget->window), WindowContext);
}
void GLWindow::Redraw(bool ForceRedraw)
{
GLWindowPrivate *prv = (GLWindowPrivate*)m_pData;
gtk_widget_draw(prv->widget, (GdkRectangle*)NULL);
}
void GLWindow::CaptureMouse()
{
}
void GLWindow::ReleaseMouse()
{
}
static void create_bitmap_and_mask_from_xpm(GdkBitmap **bitmap, GdkBitmap **mask, const char **xpm)
{
int height, width, colors;
char pixmap_buffer [(32 * 32)/8];
char mask_buffer [(32 * 32)/8];
int x, y, pix;
int transparent_color, black_color;
sscanf(xpm [0], "%d %d %d %d", &height, &width, &colors, &pix);
g_assert(height == 32);
g_assert(width == 32);
g_assert(colors == 3);
transparent_color = ' ';
black_color = '.';
for (y = 0; y < 32; y++)
{
for (x = 0; x < 32;)
{
char value = 0, maskv = 0;
for (pix = 0; pix < 8; pix++, x++)
if (xpm [4+y][x] != transparent_color)
{
maskv |= 1 << pix;
if (xpm [4+y][x] != black_color)
value |= 1 << pix;
}
pixmap_buffer [(y * 4 + x/8)-1] = value;
mask_buffer [(y * 4 + x/8)-1] = maskv;
}
}
*bitmap = gdk_bitmap_create_from_data(NULL, pixmap_buffer, 32, 32);
*mask = gdk_bitmap_create_from_data(NULL, mask_buffer, 32, 32);
}
void GLWindow::SetCursor(LC_CURSOR_TYPE Type)
{
#include "pixmaps/cr_brick.xpm"
#include "pixmaps/cr_light.xpm"
#include "pixmaps/cr_spot.xpm"
#include "pixmaps/cr_cam.xpm"
#include "pixmaps/cr_sel.xpm"
#include "pixmaps/cr_selm.xpm"
#include "pixmaps/cr_move.xpm"
#include "pixmaps/cr_rot.xpm"
#include "pixmaps/cr_paint.xpm"
#include "pixmaps/cr_erase.xpm"
#include "pixmaps/cr_pan.xpm"
#include "pixmaps/cr_rotv.xpm"
#include "pixmaps/cr_roll.xpm"
#include "pixmaps/cr_zoom.xpm"
#include "pixmaps/cr_zoomr.xpm"
// TODO: Missing LC_CURSOR_ROTATEX and LC_CURSOR_ROTATEY.
// TODO: Auto-generate xpms from bmps in the Makefile.
const char** Cursors[LC_CURSOR_COUNT] =
{
NULL, // LC_CURSOR_DEFAULT
cr_brick, // LC_CURSOR_BRICK
cr_light, // LC_CURSOR_LIGHT
cr_spot, // LC_CURSOR_SPOTLIGHT
cr_cam, // LC_CURSOR_CAMERA
cr_sel, // LC_CURSOR_SELECT
cr_selm, // LC_CURSOR_SELECT_GROUP
cr_move, // LC_CURSOR_MOVE
cr_rot, // LC_CURSOR_ROTATE
cr_rot, // LC_CURSOR_ROTATEX
cr_rot, // LC_CURSOR_ROTATEY
cr_erase, // LC_CURSOR_DELETE
cr_paint, // LC_CURSOR_PAINT
cr_zoom, // LC_CURSOR_ZOOM
cr_zoomr, // LC_CURSOR_ZOOM_REGION
cr_pan, // LC_CURSOR_PAN
cr_roll, // LC_CURSOR_ROLL
cr_rotv, // LC_CURSOR_ROTATE_VIEW
};
int Offsets[LC_CURSOR_COUNT][2] =
{
{ 0, 0 }, // LC_CURSOR_DEFAULT
{ 8, 3 }, // LC_CURSOR_BRICK
{ 15, 15 }, // LC_CURSOR_LIGHT
{ 7, 10 }, // LC_CURSOR_SPOTLIGHT
{ 15, 9 }, // LC_CURSOR_CAMERA
{ 0, 2 }, // LC_CURSOR_SELECT
{ 0, 2 }, // LC_CURSOR_SELECT_GROUP
{ 15, 15 }, // LC_CURSOR_MOVE
{ 15, 15 }, // LC_CURSOR_ROTATE
{ 15, 15 }, // LC_CURSOR_ROTATEX
{ 15, 15 }, // LC_CURSOR_ROTATEY
{ 0, 10 }, // LC_CURSOR_DELETE
{ 14, 14 }, // LC_CURSOR_PAINT
{ 15, 15 }, // LC_CURSOR_ZOOM
{ 9, 9 }, // LC_CURSOR_ZOOM_REGION
{ 15, 15 }, // LC_CURSOR_PAN
{ 15, 15 }, // LC_CURSOR_ROLL
{ 15, 15 }, // LC_CURSOR_ROTATE_VIEW
};
GLWindowPrivate *prv = (GLWindowPrivate*)m_pData;
if (prv->Cursor == Type)
return;
const char** xpm = Cursors[Type];
int x = Offsets[Type][0];
int y = Offsets[Type][1];
GdkBitmap *bitmap;
GdkBitmap *mask;
GdkCursor *cursor;
GdkColor white = {0, 0xffff, 0xffff, 0xffff};
GdkColor black = {0, 0x0000, 0x0000, 0x0000};
if (xpm != NULL)
{
create_bitmap_and_mask_from_xpm(&bitmap, &mask, xpm);
cursor = gdk_cursor_new_from_pixmap(bitmap, mask, &white, &black, x, y);
gdk_window_set_cursor(prv->widget->window, cursor);
}
else
{
cursor = gdk_cursor_new(GDK_LEFT_PTR);
gdk_window_set_cursor(prv->widget->window, cursor);
gdk_cursor_destroy(cursor);
}
prv->Cursor = Type;
}

View file

@ -1,191 +0,0 @@
//
// Small functions to help with GTK
//
#include "lc_global.h"
#include <gtk/gtk.h>
#include <gdk/gdkx.h>
#include <string.h>
#include "gtkmisc.h"
#include "globals.h"
#include "project.h"
//#include "pixmenu.h"
#include "gtktools.h"
// =============================================================================
// Pixmap functions
// Load a pixmap file from the disk
void load_pixmap (const char* filename, GdkPixmap **gdkpixmap, GdkBitmap **mask)
{
*gdkpixmap = NULL;
if (*gdkpixmap == NULL)
{
const char *dummy[] = { "1 1 1 1", " c None", " " };
*gdkpixmap = gdk_pixmap_create_from_xpm_d (GDK_ROOT_PARENT(), mask, NULL, (gchar**)dummy);
}
}
// Load a xpm file and return a pixmap widget
GtkWidget* create_pixmap (const char* filename)
{
GdkPixmap *gdkpixmap;
GdkBitmap *mask;
GtkWidget *pixmap;
load_pixmap (filename, &gdkpixmap, &mask);
pixmap = gtk_pixmap_new (gdkpixmap, mask);
gtk_widget_show (pixmap);
gdk_pixmap_unref (gdkpixmap);
gdk_pixmap_unref (mask);
return pixmap;
}
// =============================================================================
// Menu stuff
GtkWidget* menu_separator (GtkWidget *menu)
{
GtkWidget *menu_item = gtk_menu_item_new ();
gtk_menu_append (GTK_MENU (menu), menu_item);
gtk_widget_set_sensitive (menu_item, FALSE);
gtk_widget_show (menu_item);
return menu_item;
}
GtkWidget* menu_tearoff (GtkWidget *menu)
{
GtkWidget *menu_item = gtk_tearoff_menu_item_new ();
gtk_menu_append (GTK_MENU (menu), menu_item);
// gtk_widget_set_sensitive (menu_item, FALSE);
gtk_widget_show (menu_item);
return menu_item;
}
GtkWidget* create_sub_menu(GtkWidget* bar, const char* label, GtkAccelGroup* accel)
{
GtkWidget *item, *menu;
item = gtk_menu_item_new_with_mnemonic(label);
gtk_widget_show (item);
gtk_container_add (GTK_CONTAINER (bar), item);
menu = gtk_menu_new ();
gtk_menu_item_set_submenu (GTK_MENU_ITEM (item), menu);
return menu;
}
GtkWidget* create_menu_in_menu(GtkWidget* menu, const char* label, GtkAccelGroup* accel)
{
GtkWidget *item, *submenu;
item = gtk_menu_item_new_with_mnemonic(label);
gtk_widget_show (item);
gtk_container_add (GTK_CONTAINER (menu), item);
submenu = gtk_menu_new ();
gtk_menu_item_set_submenu (GTK_MENU_ITEM (item), submenu);
return submenu;
}
GtkWidget* create_menu_item(GtkWidget *menu, const char *label, GtkAccelGroup *menu_accel,
GtkSignalFunc func, GtkObject *window, int id, const char* data)
{
GtkWidget *item;
item = gtk_menu_item_new_with_mnemonic (label);
gtk_widget_show (item);
gtk_container_add (GTK_CONTAINER (menu), item);
gtk_signal_connect (GTK_OBJECT (item), "activate", GTK_SIGNAL_FUNC (func), GINT_TO_POINTER (id));
if (data != NULL)
gtk_object_set_data (window, data, item);
return item;
}
GtkWidget* create_pixmap_menu_item(GtkWidget *menu, const gchar *label, const char **pixmap, GtkAccelGroup *menu_accel,
GtkSignalFunc func, GtkObject *window, int id, const char* data)
{
GtkWidget *item, *pixmap_widget;
item = gtk_image_menu_item_new_with_mnemonic(label);
pixmap_widget = new_pixmap (GTK_WIDGET (window), pixmap);
gtk_widget_show (pixmap_widget);
gtk_image_menu_item_set_image (GTK_IMAGE_MENU_ITEM (item), pixmap_widget);
gtk_widget_show (item);
gtk_container_add (GTK_CONTAINER (menu), item);
gtk_signal_connect (GTK_OBJECT (item), "activate", GTK_SIGNAL_FUNC (func), GINT_TO_POINTER (id));
if (data != NULL)
gtk_object_set_data (window, data, item);
return item;
}
GtkWidget* create_check_menu_item(GtkWidget *menu, const char *label, GtkAccelGroup *menu_accel,
GtkSignalFunc func, GtkObject *window, int id, const char* data)
{
GtkWidget *item;
item = gtk_check_menu_item_new_with_mnemonic(label);
gtk_widget_show (item);
gtk_container_add (GTK_CONTAINER (menu), item);
gtk_signal_connect (GTK_OBJECT (item), "activate", GTK_SIGNAL_FUNC (func), GINT_TO_POINTER (id));
if (data != NULL)
gtk_object_set_data (window, data, item);
return item;
}
GtkWidget* create_radio_menu_item(GtkWidget *menu, GtkWidget *last, const char *label,
GtkAccelGroup *menu_accel, GtkSignalFunc func,
GtkObject *window, int id, const char* data)
{
GtkWidget *item;
GSList *group = NULL;
if (last != NULL)
group = gtk_radio_menu_item_group (GTK_RADIO_MENU_ITEM (last));
item = gtk_radio_menu_item_new_with_mnemonic(group, label);
gtk_widget_show (item);
gtk_container_add (GTK_CONTAINER (menu), item);
gtk_signal_connect (GTK_OBJECT (item), "activate", GTK_SIGNAL_FUNC (func), GINT_TO_POINTER (id));
if (data != NULL)
gtk_object_set_data (window, data, item);
return item;
}
GtkWidget* create_radio_menu_pixmap(GtkWidget *menu, GtkWidget *last, const char *filename,
GtkAccelGroup *menu_accel, GtkSignalFunc func,
GtkObject *window, int id, const char* data)
{
GtkWidget *item, *pixmap;
GSList *group = NULL;
if (last != NULL)
group = gtk_radio_menu_item_group (GTK_RADIO_MENU_ITEM (last));
item = gtk_radio_menu_item_new (group);
gtk_widget_show (item);
gtk_container_add (GTK_CONTAINER (menu), item);
gtk_signal_connect (GTK_OBJECT (item), "activate", GTK_SIGNAL_FUNC (func), GINT_TO_POINTER (id));
pixmap = create_pixmap (filename);
gtk_container_add (GTK_CONTAINER (item), pixmap);
if (data != NULL)
gtk_object_set_data (window, data, item);
return item;
}

View file

@ -1,25 +0,0 @@
#ifndef _GTK_MISC_H_
#define _GTK_MISC_H_
GtkWidget* create_pixmap (char* filename);
void load_pixmap (const char* filename, GdkPixmap **gdkpixmap, GdkBitmap **mask);
GtkWidget* menu_separator (GtkWidget *menu);
GtkWidget* menu_tearoff (GtkWidget *menu);
GtkWidget* create_sub_menu(GtkWidget *bar, const char *label, GtkAccelGroup *accel);
GtkWidget* create_menu_in_menu(GtkWidget *menu, const char *label, GtkAccelGroup *accel);
GtkWidget* create_menu_item(GtkWidget *menu, const char *label, GtkAccelGroup *accel,
GtkSignalFunc func, GtkObject *window, int id, const char* data);
GtkWidget* create_pixmap_menu_item(GtkWidget *menu, const char *label, const char **pixmap, GtkAccelGroup *accel,
GtkSignalFunc func, GtkObject *window, int id, const char* data);
GtkWidget* create_check_menu_item(GtkWidget *menu, const char *label, GtkAccelGroup *menu_accel,
GtkSignalFunc func, GtkObject *window, int id, const char* data);
GtkWidget* create_radio_menu_item(GtkWidget *menu, GtkWidget *last, const char *label,
GtkAccelGroup *menu_accel, GtkSignalFunc func,
GtkObject *window, int id, const char* data);
GtkWidget* create_radio_menu_pixmap(GtkWidget *menu, GtkWidget *last, const char *filename,
GtkAccelGroup *menu_accel, GtkSignalFunc func,
GtkObject *window, int id, const char* data);
#endif // _GTKMISC_H_

View file

@ -1,114 +0,0 @@
// Helper functions for GTK
//
#include <gtk/gtk.h>
#include "gtktools.h"
GtkWidget* new_pixmap(GtkWidget *widget, const char **data)
{
GdkPixmap *gdkpixmap;
GdkBitmap *mask;
GtkWidget *pixmap;
gdkpixmap = gdk_pixmap_create_from_xpm_d(widget->window, &mask, &widget->style->bg[GTK_STATE_NORMAL], (gchar**)data);
pixmap = gtk_pixmap_new (gdkpixmap, mask);
gdk_pixmap_unref (gdkpixmap);
gdk_pixmap_unref (mask);
return pixmap;
}
GtkWidget* clist_title_with_arrow(GtkWidget* clist, char col, const char* label_text)
{
GtkWidget *hbox = gtk_hbox_new (FALSE, 0);
GtkWidget *arrow = gtk_arrow_new (GTK_ARROW_DOWN, GTK_SHADOW_IN);
GtkWidget *label = gtk_label_new (label_text);
gtk_box_pack_start (GTK_BOX (hbox), label, FALSE, TRUE, 0);
gtk_box_pack_end (GTK_BOX (hbox), arrow, FALSE, TRUE, 0);
gtk_widget_show (label);
gtk_widget_show (hbox);
gtk_clist_set_column_widget (GTK_CLIST (clist), col, hbox);
return arrow;
}
void set_notebook_tab (GtkWidget *notebook, gint page_num, GtkWidget *widget)
{
gtk_notebook_set_tab_label(GTK_NOTEBOOK(notebook), gtk_notebook_get_nth_page(GTK_NOTEBOOK(notebook), page_num), widget);
/*
GtkNotebookPage *page;
GtkWidget *notebook_page;
page = (GtkNotebookPage*) g_list_nth (GTK_NOTEBOOK (notebook)->children, page_num)->data;
notebook_page = page->child;
gtk_widget_ref (notebook_page);
gtk_notebook_remove_page (GTK_NOTEBOOK (notebook), page_num);
gtk_notebook_insert_page (GTK_NOTEBOOK (notebook), notebook_page,
widget, page_num);
gtk_widget_unref (notebook_page);
*/
}
void set_button_pixmap (GtkWidget* widget, float* color)
{
if (widget->window == NULL)
return;
GdkColor c;
GdkGC* gc = gdk_gc_new(widget->window);
GdkPixmap* pixmap = gdk_pixmap_new(widget->window, widget->allocation.width - 20,
widget->allocation.height - 20, -1);
c.red = (gushort)(color[0]*0xFFFF);
c.green = (gushort)(color[1]*0xFFFF);
c.blue = (gushort)(color[2]*0xFFFF);
gdk_color_alloc (gtk_widget_get_colormap(widget), &c);
gdk_gc_set_foreground(gc, &c);
gdk_draw_rectangle (pixmap, gc, TRUE, 0, 0,
widget->allocation.width - 20, widget->allocation.height - 20);
GtkWidget* pixmapwid = gtk_pixmap_new (pixmap, (GdkBitmap*)NULL);
gtk_widget_show (pixmapwid);
gtk_container_remove (GTK_CONTAINER(widget), GTK_BIN(widget)->child);
gtk_container_add (GTK_CONTAINER(widget), pixmapwid);
gdk_gc_destroy(gc);
}
void set_button_pixmap2(GtkWidget* widget, float* color)
{
GdkColor c;
GdkGC* gc;
GdkPixmap* pixmap;
if (widget->window == NULL)
return;
if ((widget->allocation.width < 10) || (widget->allocation.height < 10))
return;
gc = gdk_gc_new (widget->window);
pixmap = gdk_pixmap_new (widget->window, widget->allocation.width - 10,
widget->allocation.height - 10, -1);
c.red = (gushort)(color[0]*0xFFFF);
c.green = (gushort)(color[1]*0xFFFF);
c.blue = (gushort)(color[2]*0xFFFF);
gdk_color_alloc (gtk_widget_get_colormap(widget), &c);
gdk_gc_set_foreground(gc, &c);
gdk_draw_rectangle (pixmap, gc, TRUE, 0, 0,
widget->allocation.width - 5, widget->allocation.height - 5);
GtkWidget* pixmapwid = gtk_pixmap_new (pixmap, (GdkBitmap*)NULL);
gtk_widget_show (pixmapwid);
gtk_container_remove (GTK_CONTAINER(widget), GTK_BIN(widget)->child);
gtk_container_add (GTK_CONTAINER(widget), pixmapwid);
gdk_gc_destroy(gc);
}

View file

@ -1,12 +0,0 @@
#ifndef _GTKTOOLS_H_
#define _GTKTOOLS_H_
GtkWidget* new_pixmap(GtkWidget* widget, const char** data);
GtkWidget* clist_title_with_arrow(GtkWidget* clist, char col, const char* label_text);
void set_notebook_tab(GtkWidget *notebook, gint page_num, GtkWidget *widget);
void set_button_pixmap(GtkWidget* widget, float* color);
void set_button_pixmap2(GtkWidget* widget, float* color);
#endif // _GTKTOOLS_H_

View file

@ -1,26 +0,0 @@
#ifndef _LC_CONFIG_H_
#define _LC_CONFIG_H_
#include <glib.h>
#define LC_LINUX
#define LC_POINTER_TO_INT GPOINTER_TO_INT
typedef gint8 lcint8;
typedef guint8 lcuint8;
typedef gint16 lcint16;
typedef guint16 lcuint16;
typedef gint32 lcint32;
typedef guint32 lcuint32;
typedef gint64 lcint64;
typedef guint64 lcuint64;
#if G_BYTE_ORDER == G_LITTLE_ENDIAN
#define LC_LITTLE_ENDIAN
#else
#define LC_BIG_ENDIAN
#endif
#endif // _LC_CONFIG_H_

View file

@ -1,346 +0,0 @@
// LibDlg.cpp : implementation file
//
#include "lc_global.h"
#include <limits.h>
//#include "leocad.h"
#include "libdlg.h"
//#include "GroupDlg.h"
//#include "Print.h"
//#include "Tools.h"
#include "project.h"
#include "pieceinf.h"
#include "system.h"
#include "lc_library.h"
#include "lc_application.h"
bool LibraryDialog::HandleCommand(int id)
{
switch (id)
{
case LC_LIBDLG_FILE_OPEN:
{
lcGetPiecesLibrary()->LoadCategories(NULL);
// UpdateTree();
return true;
}
case LC_LIBDLG_FILE_SAVE:
{
lcGetPiecesLibrary()->DoSaveCategories(false);
return true;
}
case LC_LIBDLG_FILE_SAVEAS:
{
lcGetPiecesLibrary()->DoSaveCategories(true);
return true;
}
/*
case LC_LIBDLG_FILE_PRINTCATALOG:
{
PRINT_PARAMS* param = (PRINT_PARAMS*)malloc(sizeof(PRINT_PARAMS));
param->pParent = this;
param->pMainFrame = (CFrameWnd*)AfxGetMainWnd();
AfxBeginThread(PrintCatalogFunction, param);
return true;
}
*/
case LC_LIBDLG_CATEGORY_RESET:
{
if (SystemDoMessageBox("Are you sure you want to reset the categories?", LC_MB_YESNO | LC_MB_ICONQUESTION) == LC_YES)
{
lcGetPiecesLibrary()->ResetCategories();
// UpdateList();
// UpdateTree();
}
return true;
}
case LC_LIBDLG_CATEGORY_NEW:
{
LC_CATEGORYDLG_OPTS Opts;
Opts.Name = "New Category";
Opts.Keywords = "";
if (SystemDoDialog(LC_DLG_EDITCATEGORY, &Opts))
{
lcGetPiecesLibrary()->AddCategory(Opts.Name, Opts.Keywords);
}
// UpdateTree();
return true;
}
case LC_LIBDLG_CATEGORY_REMOVE:
{
/*
HTREEITEM Item = m_Tree.GetSelectedItem();
if (Item == NULL)
break;
PiecesLibrary* Lib = lcGetPiecesLibrary();
CString CategoryName = m_Tree.GetItemText(Item);
int Index = Lib->FindCategoryIndex((const char*)CategoryName);
if (Index == -1)
break;
char Msg[1024];
String Name = Lib->GetCategoryName(Index);
sprintf(Msg, "Are you sure you want to remove the %s category?", Name);
if (SystemDoMessageBox(Msg, LC_MB_YESNO | LC_MB_ICONQUESTION) == LC_YES)
{
Lib->RemoveCategory(Index);
}
UpdateTree();
*/
return true;
}
case LC_LIBDLG_CATEGORY_EDIT:
{
/*
HTREEITEM Item = m_Tree.GetSelectedItem();
if (Item == NULL)
break;
PiecesLibrary* Lib = lcGetPiecesLibrary();
CString CategoryName = m_Tree.GetItemText(Item);
int Index = Lib->FindCategoryIndex((const char*)CategoryName);
if (Index == -1)
break;
LC_CATEGORYDLG_OPTS Opts;
Opts.Name = Lib->GetCategoryName(Index);
Opts.Keywords = Lib->GetCategoryKeywords(Index);
if (SystemDoDialog(LC_DLG_EDITCATEGORY, &Opts))
{
String OldName = Lib->GetCategoryName(Index);
Lib->SetCategory(Index, Opts.Name, Opts.Keywords);
}
UpdateTree();
*/
return true;
}
}
// return CDialog::OnCommand(wParam, lParam);
return true;
}
/*
void CLibraryDlg::UpdateList()
{
m_List.DeleteAllItems();
m_List.SetRedraw(false);
PiecesLibrary *Lib = lcGetPiecesLibrary();
HTREEITEM CategoryItem = m_Tree.GetSelectedItem();
CString CategoryName = m_Tree.GetItemText(CategoryItem);
int CategoryIndex = Lib->FindCategoryIndex((const char*)CategoryName);
if (CategoryIndex != -1)
{
PtrArray<PieceInfo> SinglePieces, GroupedPieces;
Lib->GetCategoryEntries(CategoryIndex, false, SinglePieces, GroupedPieces);
for (int i = 0; i < SinglePieces.GetSize(); i++)
{
PieceInfo* Info = SinglePieces[i];
LVITEM lvi;
lvi.mask = LVIF_TEXT | LVIF_PARAM;
lvi.iItem = 0;
lvi.iSubItem = 0;
lvi.lParam = (LPARAM)Info;
lvi.pszText = Info->m_strDescription;
int idx = m_List.InsertItem(&lvi);
m_List.SetItemText(idx, 1, Info->m_strName);
}
}
else
{
if (CategoryName == "Unassigned")
{
// Test each piece against all categories.
for (int i = 0; i < Lib->GetPieceCount(); i++)
{
PieceInfo* Info = Lib->GetPieceInfo(i);
for (int j = 0; j < Lib->GetNumCategories(); j++)
{
if (Lib->PieceInCategory(Info, Lib->GetCategoryKeywords(j)))
break;
}
if (j == Lib->GetNumCategories())
{
LVITEM lvi;
lvi.mask = LVIF_TEXT | LVIF_PARAM;
lvi.iItem = 0;
lvi.iSubItem = 0;
lvi.lParam = (LPARAM)Info;
lvi.pszText = Info->m_strDescription;
int idx = m_List.InsertItem(&lvi);
m_List.SetItemText(idx, 1, Info->m_strName);
}
}
}
else if (CategoryName == "Pieces")
{
for (int i = 0; i < Lib->GetPieceCount(); i++)
{
PieceInfo* Info = Lib->GetPieceInfo(i);
LVITEM lvi;
lvi.mask = LVIF_TEXT | LVIF_PARAM;
lvi.iItem = 0;
lvi.iSubItem = 0;
lvi.lParam = (LPARAM)Info;
lvi.pszText = Info->m_strDescription;
int idx = m_List.InsertItem(&lvi);
m_List.SetItemText(idx, 1, Info->m_strName);
}
}
}
m_List.SortItems((PFNLVCOMPARE)ListCompare, m_SortColumn);
m_List.SetRedraw(true);
}
void CLibraryDlg::UpdateTree()
{
m_Tree.SetRedraw(false);
m_Tree.DeleteAllItems();
HTREEITEM Root = m_Tree.InsertItem(TVIF_IMAGE|TVIF_SELECTEDIMAGE|TVIF_TEXT, "Pieces", 0, 1, 0, 0, 0, TVI_ROOT, TVI_SORT);
PiecesLibrary *Lib = lcGetPiecesLibrary();
for (int i = 0; i < Lib->GetNumCategories(); i++)
m_Tree.InsertItem(TVIF_IMAGE|TVIF_SELECTEDIMAGE|TVIF_PARAM|TVIF_TEXT, Lib->GetCategoryName(i), 0, 1, 0, 0, 0, Root, TVI_SORT);
m_Tree.InsertItem(TVIF_IMAGE|TVIF_SELECTEDIMAGE|TVIF_PARAM|TVIF_TEXT, "Unassigned", 0, 1, 0, 0, 0, Root, TVI_LAST);
m_Tree.Expand(Root, TVE_EXPAND);
m_Tree.SetRedraw(true);
m_Tree.Invalidate();
}
void CLibraryDlg::OnSelChangedTree(NMHDR* pNMHDR, LRESULT* pResult)
{
NM_TREEVIEW* pNMTreeView = (NM_TREEVIEW*)pNMHDR;
UpdateList();
*pResult = 0;
}
void CLibraryDlg::OnCancel()
{
// Check if it's ok to close the dialog
if (!lcGetPiecesLibrary()->SaveCategories())
return;
CDialog::OnCancel();
}
void CLibraryDlg::OnOK()
{
// Check if it's ok to close the dialog
if (!lcGetPiecesLibrary()->SaveCategories())
return;
CDialog::OnOK();
}
BOOL CLibraryDlg::ContinueModal()
{
HTREEITEM h = m_Tree.GetSelectedItem();
BOOL bValid = (h != m_Tree.GetRootItem()) && (h != NULL);
EnableControl(LC_LIBDLG_GROUP_RENAME, bValid);
EnableControl(LC_LIBDLG_GROUP_DELETE, bValid);
return CDialog::ContinueModal();
}
void CLibraryDlg::EnableControl(UINT nID, BOOL bEnable)
{
GetMenu()->GetSubMenu(1)->EnableMenuItem(nID, MF_BYCOMMAND | (bEnable ? MF_ENABLED : (MF_DISABLED | MF_GRAYED)));
int state = m_wndToolBar.GetToolBarCtrl().GetState(nID) & ~TBSTATE_ENABLED;
if (bEnable)
state |= TBSTATE_ENABLED;
m_wndToolBar.GetToolBarCtrl().SetState(nID, state);
}
BOOL CLibraryDlg::OnToolTipText(UINT, NMHDR* pNMHDR, LRESULT* pResult)
{
ASSERT(pNMHDR->code == TTN_NEEDTEXTA || pNMHDR->code == TTN_NEEDTEXTW);
// allow top level routing frame to handle the message
if (GetRoutingFrame() != NULL)
return false;
// need to handle both ANSI and UNICODE versions of the message
TOOLTIPTEXTA* pTTTA = (TOOLTIPTEXTA*)pNMHDR;
TOOLTIPTEXTW* pTTTW = (TOOLTIPTEXTW*)pNMHDR;
CString cstTipText;
UINT nID = pNMHDR->idFrom;
if (pNMHDR->code == TTN_NEEDTEXTA && (pTTTA->uFlags & TTF_IDISHWND) ||
pNMHDR->code == TTN_NEEDTEXTW && (pTTTW->uFlags & TTF_IDISHWND))
{
// idFrom is actually the HWND of the tool
nID = ((UINT)(WORD)::GetDlgCtrlID((HWND)nID));
}
if (nID != 0) // will be zero on a separator
{
cstTipText.LoadString(nID);
}
// Non-UNICODE Strings only are shown in the tooltip window...
if (pNMHDR->code == TTN_NEEDTEXTA)
lstrcpyn(pTTTA->szText, cstTipText, (sizeof(pTTTA->szText)/sizeof(pTTTA->szText[0])));
else
_mbstowcsz(pTTTW->szText, cstTipText, (sizeof(pTTTW->szText)/sizeof(pTTTW->szText[0])));
*pResult = 0;
// bring the tooltip window above other popup windows
::SetWindowPos(pNMHDR->hwndFrom, HWND_TOP, 0, 0, 0, 0,
SWP_NOACTIVATE|SWP_NOSIZE|SWP_NOMOVE);
return true; // message was handled
}
void CLibraryDlg::OnListColumnClick(NMHDR* pNMHDR, LRESULT* pResult)
{
NM_LISTVIEW* pNMListView = (NM_LISTVIEW*)pNMHDR;
// Save the column index.
m_SortColumn = pNMListView->iSubItem;
m_List.SortItems((PFNLVCOMPARE)ListCompare, m_SortColumn);
*pResult = 0;
}
*/

View file

@ -1,35 +0,0 @@
#ifndef _LIBDLG_H_
#define _LIBDLG_H_
class PieceInfo;
// =============================================================================
// LibraryDialog class
enum
{
LC_LIBDLG_FILE_RESET,
LC_LIBDLG_FILE_OPEN,
LC_LIBDLG_FILE_SAVE,
LC_LIBDLG_FILE_SAVEAS,
LC_LIBDLG_FILE_PRINTCATALOG,
LC_LIBDLG_FILE_RETURN,
LC_LIBDLG_FILE_CANCEL,
LC_LIBDLG_CATEGORY_NEW,
LC_LIBDLG_CATEGORY_REMOVE,
LC_LIBDLG_CATEGORY_EDIT,
LC_LIBDLG_CATEGORY_RESET,
LC_LIBDLG_GROUP_INSERT,
LC_LIBDLG_GROUP_DELETE,
LC_LIBDLG_GROUP_EDIT,
LC_LIBDLG_GROUP_MOVEUP,
LC_LIBDLG_GROUP_MOVEDOWN,
};
class LibraryDialog
{
public:
bool HandleCommand(int id);
};
#endif // _LIBDLG_H_

View file

@ -1,160 +0,0 @@
//
// Linux OpenGL functions
//
#include <dlfcn.h>
#include <stdio.h>
#include "lc_global.h"
#include "opengl.h"
static void* gl_module;
// =============================================================================
// Function pointers
PFNGLXCHOOSEVISUAL pfnglXChooseVisual;
PFNGLXCREATECONTEXT pfnglXCreateContext;
PFNGLXDESTROYCONTEXT pfnglXDestroyContext;
PFNGLXMAKECURRENT pfnglXMakeCurrent;
PFNGLXCOPYCONTEXT pfnglXCopyContext;
PFNGLXSWAPBUFFERS pfnglXSwapBuffers;
PFNGLXCREATEGLXPIXMAP pfnglXCreateGLXPixmap;
PFNGLXDESTROYGLXPIXMAP pfnglXDestroyGLXPixmap;
PFNGLXQUERYEXTENSION pfnglXQueryExtension;
PFNGLXQUERYVERSION pfnglXQueryVersion;
PFNGLXISDIRECT pfnglXIsDirect;
PFNGLXGETCONFIG pfnglXGetConfig;
PFNGLXGETCURRENTCONTEXT pfnglXGetCurrentContext;
PFNGLXGETCURRENTDRAWABLE pfnglXGetCurrentDrawable;
PFNGLXWAITGL pfnglXWaitGL;
PFNGLXWAITX pfnglXWaitX;
PFNGLXUSEXFONT pfnglXUseXFont;
PFNGLXQUERYEXTENSIONSSTRING pfnglXQueryExtensionsString;
PFNGLXQUERYSERVERSTRING pfnglXQueryServerString;
PFNGLXGETCLIENTSTRING pfnglXGetClientString;
//PFNGLXCREATEGLXPIXMAPMESA pfnglXCreateGLXPixmapMESA;
//PFNGLXRELEASEBUFFERSMESA pfnglXReleaseBuffersMESA;
//PFNGLXCOPYSUBBUFFERMESA pfnglXCopySubBufferMESA;
//PFNGLXSET3DFXMODEMESA pfnglXSet3DfxModeMESA;
//PFNGLXGETVIDEOSYNCSGI pfnglXGetVideoSyncSGI;
//PFNGLXWAITVIDEOSYNCSGI pfnglXWaitVideoSyncSGI;
PFNGLXGETPROCADDRESSARB pfnglXGetProcAddressARB;
// =============================================================================
// Global functions
void* Sys_GLGetProc (const char *symbol)
{
void* func = dlsym (gl_module, symbol);
const char* error = dlerror ();
if (error)
printf ("Error loading OpenGL library.\n%s\n", error);
return func;
}
void* Sys_GLGetExtension (const char *symbol)
{
if (pfnglXGetProcAddressARB == NULL)
return NULL;
else
return pfnglXGetProcAddressARB ((GLubyte*)symbol);
}
bool Sys_GLOpenLibrary (const char* libname)
{
const char *error;
if (libname)
{
gl_module = dlopen (libname, RTLD_LAZY|RTLD_GLOBAL);
error = dlerror ();
if (error)
printf ("Error loading OpenGL library.\n%s\n", error);
}
if (gl_module == NULL)
{
gl_module = dlopen ("libGL.so.1", RTLD_LAZY|RTLD_GLOBAL);
error = dlerror ();
if (error)
printf ("Error loading OpenGL library.\n%s\n", error);
}
if (gl_module == NULL)
{
gl_module = dlopen ("libMesaGL.so.1", RTLD_LAZY|RTLD_GLOBAL);
error = dlerror ();
if (error)
printf ("Error loading OpenGL library.\n%s\n", error);
}
if (gl_module == NULL)
return false;
pfnglXChooseVisual = (PFNGLXCHOOSEVISUAL) Sys_GLGetProc ("glXChooseVisual");
pfnglXCreateContext = (PFNGLXCREATECONTEXT) Sys_GLGetProc ("glXCreateContext");
pfnglXDestroyContext = (PFNGLXDESTROYCONTEXT) Sys_GLGetProc ("glXDestroyContext");
pfnglXMakeCurrent = (PFNGLXMAKECURRENT) Sys_GLGetProc ("glXMakeCurrent");
pfnglXCopyContext = (PFNGLXCOPYCONTEXT) Sys_GLGetProc ("glXCopyContext");
pfnglXSwapBuffers = (PFNGLXSWAPBUFFERS) Sys_GLGetProc ("glXSwapBuffers");
pfnglXCreateGLXPixmap = (PFNGLXCREATEGLXPIXMAP) Sys_GLGetProc ("glXCreateGLXPixmap");
pfnglXDestroyGLXPixmap = (PFNGLXDESTROYGLXPIXMAP) Sys_GLGetProc ("glXDestroyGLXPixmap");
pfnglXQueryExtension = (PFNGLXQUERYEXTENSION) Sys_GLGetProc ("glXQueryExtension");
pfnglXQueryVersion = (PFNGLXQUERYVERSION) Sys_GLGetProc ("glXQueryVersion");
pfnglXIsDirect = (PFNGLXISDIRECT) Sys_GLGetProc ("glXIsDirect");
pfnglXGetConfig = (PFNGLXGETCONFIG) Sys_GLGetProc ("glXGetConfig");
pfnglXGetCurrentContext = (PFNGLXGETCURRENTCONTEXT) Sys_GLGetProc ("glXGetCurrentContext");
pfnglXGetCurrentDrawable = (PFNGLXGETCURRENTDRAWABLE) Sys_GLGetProc ("glXGetCurrentDrawable");
pfnglXWaitGL = (PFNGLXWAITGL) Sys_GLGetProc ("glXWaitGL");
pfnglXWaitX = (PFNGLXWAITX) Sys_GLGetProc ("glXWaitX");
pfnglXUseXFont = (PFNGLXUSEXFONT) Sys_GLGetProc ("glXUseXFont");
pfnglXQueryExtensionsString = (PFNGLXQUERYEXTENSIONSSTRING) Sys_GLGetProc ("glXQueryExtensionsString");
pfnglXQueryServerString = (PFNGLXQUERYSERVERSTRING) Sys_GLGetProc ("glXQueryServerString");
pfnglXGetClientString = (PFNGLXGETCLIENTSTRING) Sys_GLGetProc ("glXGetClientString");
// pfnglXCreateGLXPixmapMESA = (PFNGLXCREATEGLXPIXMAPMESA) Sys_GLGetProc ("glXCreateGLXPixmapMESA");
// pfnglXReleaseBuffersMESA = (PFNGLXRELEASEBUFFERSMESA) Sys_GLGetProc ("glXReleaseBuffersMESA");
// pfnglXCopySubBufferMESA = (PFNGLXCOPYSUBBUFFERMESA) Sys_GLGetProc ("glXCopySubBufferMESA");
// pfnglXSet3DfxModeMESA = (PFNGLXSET3DFXMODEMESA) Sys_GLGetProc ("glXSet3DfxModeMESA");
// pfnglXGetVideoSyncSGI = (PFNGLXGETVIDEOSYNCSGI) Sys_GLGetProc ("glXGetVideoSyncSGI");
// pfnglXWaitVideoSyncSGI = (PFNGLXWAITVIDEOSYNCSGI) Sys_GLGetProc ("glXWaitVideoSyncSGI");
pfnglXGetProcAddressARB = (PFNGLXGETPROCADDRESSARB) Sys_GLGetProc ("glXGetProcAddressARB");
return true;
}
void Sys_GLCloseLibrary ()
{
if (gl_module)
{
dlclose (gl_module);
gl_module = NULL;
}
pfnglXChooseVisual = NULL;
pfnglXCreateContext = NULL;
pfnglXDestroyContext = NULL;
pfnglXMakeCurrent = NULL;
pfnglXCopyContext = NULL;
pfnglXSwapBuffers = NULL;
pfnglXCreateGLXPixmap = NULL;
pfnglXDestroyGLXPixmap = NULL;
pfnglXQueryExtension = NULL;
pfnglXQueryVersion = NULL;
pfnglXIsDirect = NULL;
pfnglXGetConfig = NULL;
pfnglXGetCurrentContext = NULL;
pfnglXGetCurrentDrawable = NULL;
pfnglXWaitGL = NULL;
pfnglXWaitX = NULL;
pfnglXUseXFont = NULL;
pfnglXQueryExtensionsString = NULL;
pfnglXQueryServerString = NULL;
pfnglXGetClientString = NULL;
// pfnglXCreateGLXPixmapMESA = NULL;
// pfnglXReleaseBuffersMESA = NULL;
// pfnglXCopySubBufferMESA = NULL;
// pfnglXSet3DfxModeMESA = NULL;
// pfnglXGetVideoSyncSGI = NULL;
// pfnglXWaitVideoSyncSGI = NULL;
pfnglXGetProcAddressARB = NULL;
}

View file

@ -1,114 +0,0 @@
#ifndef _LINUX_GL_H_
#define _LINUX_GL_H_
// =============================================================================
// GLX functions typedefs
typedef XVisualInfo* (*PFNGLXCHOOSEVISUAL) (Display *dpy, int screen, int *attribList);
typedef GLXContext (*PFNGLXCREATECONTEXT) (Display *dpy, XVisualInfo *vis, GLXContext shareList, Bool direct);
typedef void (*PFNGLXDESTROYCONTEXT) (Display *dpy, GLXContext ctx);
typedef Bool (*PFNGLXMAKECURRENT) (Display *dpy, GLXDrawable drawable, GLXContext ctx);
typedef void (*PFNGLXCOPYCONTEXT) (Display *dpy, GLXContext src, GLXContext dst, GLuint mask);
typedef void (*PFNGLXSWAPBUFFERS) (Display *dpy, GLXDrawable drawable);
typedef GLXPixmap (*PFNGLXCREATEGLXPIXMAP) (Display *dpy, XVisualInfo *visual, Pixmap pixmap);
typedef void (*PFNGLXDESTROYGLXPIXMAP) (Display *dpy, GLXPixmap pixmap);
typedef Bool (*PFNGLXQUERYEXTENSION) (Display *dpy, int *errorb, int *event);
typedef Bool (*PFNGLXQUERYVERSION) (Display *dpy, int *maj, int *min);
typedef Bool (*PFNGLXISDIRECT) (Display *dpy, GLXContext ctx);
typedef int (*PFNGLXGETCONFIG) (Display *dpy, XVisualInfo *visual, int attrib, int *value);
typedef GLXContext (*PFNGLXGETCURRENTCONTEXT) (void);
typedef GLXDrawable (*PFNGLXGETCURRENTDRAWABLE) (void);
typedef void (*PFNGLXWAITGL) (void);
typedef void (*PFNGLXWAITX) (void);
typedef void (*PFNGLXUSEXFONT) (Font font, int first, int count, int list);
// GLX 1.1 and later
typedef const char* (*PFNGLXQUERYEXTENSIONSSTRING) (Display *dpy, int screen);
typedef const char* (*PFNGLXQUERYSERVERSTRING) (Display *dpy, int screen, int name);
typedef const char* (*PFNGLXGETCLIENTSTRING) (Display *dpy, int name);
// GLX_MESA_pixmap_colormap
typedef GLXPixmap (*PFNGLXCREATEGLXPIXMAPMESA) (Display *dpy, XVisualInfo *visual, Pixmap pixmap, Colormap cmap);
// GLX_MESA_release_buffers
typedef Bool (*PFNGLXRELEASEBUFFERSMESA) (Display *dpy, GLXDrawable d);
// GLX_MESA_copy_sub_buffer
typedef void (*PFNGLXCOPYSUBBUFFERMESA) (Display *dpy, GLXDrawable drawable, int x, int y, int width, int height);
// GLX_MESA_set_3dfx_mode
typedef GLboolean (*PFNGLXSET3DFXMODEMESA) (GLint mode);
// GLX_SGI_video_sync
typedef int (*PFNGLXGETVIDEOSYNCSGI) (unsigned int *count);
typedef int (*PFNGLXWAITVIDEOSYNCSGI) (int divisor, int remainder, unsigned int *count);
// GLX_ARB_get_proc_address
typedef void* (*PFNGLXGETPROCADDRESSARB) (const GLubyte *procName);
// =============================================================================
// GLX extern declarations
extern PFNGLXCHOOSEVISUAL pfnglXChooseVisual;
extern PFNGLXCREATECONTEXT pfnglXCreateContext;
extern PFNGLXDESTROYCONTEXT pfnglXDestroyContext;
extern PFNGLXMAKECURRENT pfnglXMakeCurrent;
extern PFNGLXCOPYCONTEXT pfnglXCopyContext;
extern PFNGLXSWAPBUFFERS pfnglXSwapBuffers;
extern PFNGLXCREATEGLXPIXMAP pfnglXCreateGLXPixmap;
extern PFNGLXDESTROYGLXPIXMAP pfnglXDestroyGLXPixmap;
extern PFNGLXQUERYEXTENSION pfnglXQueryExtension;
extern PFNGLXQUERYVERSION pfnglXQueryVersion;
extern PFNGLXISDIRECT pfnglXIsDirect;
extern PFNGLXGETCONFIG pfnglXGetConfig;
extern PFNGLXGETCURRENTCONTEXT pfnglXGetCurrentContext;
extern PFNGLXGETCURRENTDRAWABLE pfnglXGetCurrentDrawable;
extern PFNGLXWAITGL pfnglXWaitGL;
extern PFNGLXWAITX pfnglXWaitX;
extern PFNGLXUSEXFONT pfnglXUseXFont;
extern PFNGLXQUERYEXTENSIONSSTRING pfnglXQueryExtensionsString;
extern PFNGLXQUERYSERVERSTRING pfnglXQueryServerString;
extern PFNGLXGETCLIENTSTRING pfnglXGetClientString;
//extern PFNGLXCREATEGLXPIXMAPMESA pfnglXCreateGLXPixmapMESA;
//extern PFNGLXRELEASEBUFFERSMESA pfnglXReleaseBuffersMESA;
//extern PFNGLXCOPYSUBBUFFERMESA pfnglXCopySubBufferMESA;
//extern PFNGLXSET3DFXMODEMESA pfnglXSet3DfxModeMESA;
//extern PFNGLXGETVIDEOSYNCSGI pfnglXGetVideoSyncSGI;
//extern PFNGLXWAITVIDEOSYNCSGI pfnglXWaitVideoSyncSGI;
extern PFNGLXGETPROCADDRESSARB pfnglXGetProcAddressARB;
// =============================================================================
// Replace GLX functions
#define glXChooseVisual pfnglXChooseVisual;
#define glXCreateContext pfnglXCreateContext;
#define glXDestroyContext pfnglXDestroyContext;
#define glXMakeCurrent pfnglXMakeCurrent;
#define glXCopyContext pfnglXCopyContext;
#define glXSwapBuffers pfnglXSwapBuffers;
#define glXCreateGLXPixmap pfnglXCreateGLXPixmap;
#define glXDestroyGLXPixmap pfnglXDestroyGLXPixmap;
#define glXQueryExtension pfnglXQueryExtension;
#define glXQueryVersion pfnglXQueryVersion;
#define glXIsDirect pfnglXIsDirect;
#define glXGetConfig pfnglXGetConfig;
#define glXGetCurrentContext pfnglXGetCurrentContext;
#define glXGetCurrentDrawable pfnglXGetCurrentDrawable;
#define glXWaitGL pfnglXWaitGL;
#define glXWaitX pfnglXWaitX;
#define glXUseXFont pfnglXUseXFont;
#define glXQueryExtensionsString pfnglXQueryExtensionsString;
#define glXQueryServerString pfnglXQueryServerString;
#define glXGetClientString pfnglXGetClientString;
//#define glXCreateGLXPixmapMESA pfnglXCreateGLXPixmapMESA;
//#define glXReleaseBuffersMESA pfnglXReleaseBuffersMESA;
//#define glXCopySubBufferMESA pfnglXCopySubBufferMESA;
//#define glXSet3DfxModeMESA pfnglXSet3DfxModeMESA;
//#define glXGetVideoSyncSGI pfnglXGetVideoSyncSGI;
//#define glXWaitVideoSyncSGI pfnglXWaitVideoSyncSGI;
#define glXGetProcAddressARB pfnglXGetProcAddressARB;
#endif // _LINUX_GL_H_

View file

@ -1,783 +0,0 @@
#include "lc_global.h"
#include <gdk/gdkkeysyms.h>
#include <gtk/gtk.h>
#include <gdk/gdkx.h>
#include <stdlib.h>
#include <stdio.h>
#include <pwd.h>
#include <unistd.h>
#include <string.h>
#include <sys/stat.h>
#include "opengl.h"
#include "project.h"
#include "toolbar.h"
#include "globals.h"
#include "main.h"
#include "system.h"
#include "dialogs.h"
#include "view.h"
#include "lc_application.h"
#include "lc_library.h"
#include "preview.h"
#include "camera.h"
#include "pieceinf.h"
View* view;
void create_main_menu (GtkObject *window, GtkWidget *vbox);
// Variables
//GtkWidget *main_window;
GtkWidget *drawing_area;
static GtkWidget* main_hbox;
static GtkWidget* drawing_frame;
static GtkWidget* drawing_parent;
static GtkWidget* pieces_frame;
static GtkWidget* pieces_parent;
static gboolean pieces_floating;
static gboolean pieces_visible;
static gint pieces_width;
static char app_path[PATH_MAX];
static char lib_path[] = LC_INSTALL_PREFIX"/share/leocad/";
bool ignore_commands = false;
PieceInfo *dragged_piece;
const GtkTargetEntry drag_target_list[] = {{ (gchar*)"application/x-leocat", GTK_TARGET_SAME_APP, 0}};
static void update_window_layout ();
static gint main_quit (GtkWidget *widget, GdkEvent* event, gpointer data);
// =============================================================================
// Static functions
static void init_paths (char *argv0)
{
char temppath[PATH_MAX];
char *home;
home = getenv ("HOME");
if (home == NULL)
{
uid_t id = getuid();
struct passwd *pwd;
setpwent();
while ((pwd = getpwent()) != NULL)
if (pwd->pw_uid == id)
{
home = pwd->pw_dir;
break;
}
endpwent();
}
strcpy (temppath, argv0);
if (!strrchr(temppath, '/'))
{
char *path;
char *last;
int found;
found = 0;
path = getenv("PATH");
do
{
temppath[0] = '\0';
last = strchr(path, ':');
if (!last)
last = path + strlen (path);
if (*path == '~')
{
if (home)
strcpy(temppath, home);
else
strcpy(temppath, ".");
path++;
}
if (last > (path+1))
{
strncat(temppath, path, (last-path));
strcat(temppath, "/");
}
strcat (temppath, "./");
strcat (temppath, argv0);
if (access(temppath, X_OK) == 0 )
found++;
path = last+1;
} while (*last && !found);
}
else
argv0 = strrchr (argv0, '/') + 1;
if (realpath (temppath, app_path))
*(strrchr (app_path, '/') + 1) = '\0';
}
// Functions
void OnCommandDirect(GtkWidget *w, gpointer data)
{
if (ignore_commands)
return;
lcGetActiveProject()->HandleCommand((LC_COMMANDS)GPOINTER_TO_INT(data), 0);
}
static void view_destroy (GtkWidget *widget, gpointer data)
{
delete (View*)data;
}
void OnCommand(GtkWidget* widget, gpointer data)
{
Project* project = lcGetActiveProject();
int id = GPOINTER_TO_INT(data);
if (ignore_commands)
return;
if (id >= ID_FILE_RECENT1 && id <= ID_FILE_RECENT4)
{
project->HandleCommand(LC_FILE_RECENT, id - ID_FILE_RECENT1);
return;
}
if (id >= ID_ACTION_SELECT && id <= ID_ACTION_ROLL)
{
project->SetAction(id - ID_ACTION_SELECT);
return;
}
if (id >= ID_CAMERA_FIRST && id <= ID_CAMERA_LAST)
{
project->HandleCommand(LC_VIEW_CAMERA_MENU, id - ID_CAMERA_FIRST);
return;
}
switch (id)
{
case ID_FILE_EXIT:
{
main_quit (NULL, NULL, NULL);
} break;
case ID_SNAP_A:
{
project->HandleCommand(LC_TOOLBAR_SNAPMENU, 5);
} break;
case ID_SNAP_X:
{
project->HandleCommand(LC_TOOLBAR_SNAPMENU, 0);
} break;
case ID_SNAP_Y:
{
project->HandleCommand(LC_TOOLBAR_SNAPMENU, 1);
} break;
case ID_SNAP_Z:
{
project->HandleCommand(LC_TOOLBAR_SNAPMENU, 2);
} break;
case ID_SNAP_ALL:
{
project->HandleCommand(LC_TOOLBAR_SNAPMENU, 3);
} break;
case ID_SNAP_NONE:
{
project->HandleCommand(LC_TOOLBAR_SNAPMENU, 4);
} break;
case ID_SNAP_ON:
{
project->HandleCommand(LC_TOOLBAR_SNAPMENU, 6);
} break;
case ID_LOCK_X:
{
project->HandleCommand(LC_TOOLBAR_LOCKMENU, 0);
} break;
case ID_LOCK_Y:
{
project->HandleCommand(LC_TOOLBAR_LOCKMENU, 1);
} break;
case ID_LOCK_Z:
{
project->HandleCommand(LC_TOOLBAR_LOCKMENU, 2);
} break;
case ID_LOCK_NONE:
{
project->HandleCommand(LC_TOOLBAR_LOCKMENU, 3);
} break;
case ID_LOCK_ON:
{
project->HandleCommand(LC_TOOLBAR_LOCKMENU, 4);
} break;
case ID_VIEW_CREATE:
{
GtkWidget *wnd, *w, *frame;
wnd = gtk_window_new (GTK_WINDOW_TOPLEVEL);
// gtk_window_set_transient_for (GTK_WINDOW (wnd), GTK_WINDOW (((GtkWidget*)(*main_window))));
gtk_window_set_title (GTK_WINDOW (wnd), "View");
// gtk_window_set_default_size (GTK_WINDOW (pieces_parent), pieces_width, -1);
frame = gtk_frame_new (NULL);
gtk_widget_show (frame);
gtk_container_add (GTK_CONTAINER (wnd), frame);
gtk_frame_set_shadow_type (GTK_FRAME (frame), GTK_SHADOW_IN);
View *v = new View (project, view);
v->CreateFromWindow (&w);
gtk_container_add (GTK_CONTAINER (frame), w);
gtk_widget_show (w);
gtk_signal_connect (GTK_OBJECT (wnd), "destroy", GTK_SIGNAL_FUNC (view_destroy), v);
gtk_widget_show (wnd);
} break;
case ID_VIEW_TOOLBAR_STANDARD:
{
if (GTK_WIDGET_VISIBLE (main_toolbar.handle_box))
gtk_widget_hide (main_toolbar.handle_box);
else
gtk_widget_show (main_toolbar.handle_box);
} break;
case ID_VIEW_TOOLBAR_DRAWING:
{
if (GTK_WIDGET_VISIBLE (tool_toolbar.handle_box))
gtk_widget_hide (tool_toolbar.handle_box);
else
gtk_widget_show (tool_toolbar.handle_box);
} break;
case ID_VIEW_TOOLBAR_ANIMATION:
{
if (GTK_WIDGET_VISIBLE (anim_toolbar.handle_box))
gtk_widget_hide (anim_toolbar.handle_box);
else
gtk_widget_show (anim_toolbar.handle_box);
} break;
case ID_VIEW_TOOLBAR_MODIFY:
{
modifydlg_toggle ();
} break;
case ID_VIEW_TOOLBAR_PIECES:
{
gpointer floating = gtk_object_get_data (GTK_OBJECT (((GtkWidget*)(*main_window))), "menu_view_toolbar_floating");
if (pieces_visible)
{
pieces_visible = FALSE;
gtk_widget_set_sensitive (GTK_WIDGET (floating), FALSE);
}
else
{
pieces_visible = TRUE;
gtk_widget_set_sensitive (GTK_WIDGET (floating), TRUE);
}
update_window_layout ();
} break;
case ID_VIEW_TOOLBAR_FLOATING:
{
if (pieces_floating)
pieces_floating = FALSE;
else
pieces_floating = TRUE;
update_window_layout ();
} break;
case ID_VIEW_TOOLBAR_BOTH:
{
gtk_toolbar_set_style (GTK_TOOLBAR (main_toolbar.toolbar), GTK_TOOLBAR_BOTH);
gtk_toolbar_set_style (GTK_TOOLBAR (tool_toolbar.toolbar), GTK_TOOLBAR_BOTH);
gtk_toolbar_set_style (GTK_TOOLBAR (anim_toolbar.toolbar), GTK_TOOLBAR_BOTH);
gtk_widget_set_usize (main_toolbar.handle_box, -1, -1);
gtk_widget_set_usize (tool_toolbar.handle_box, -1, -1);
gtk_widget_set_usize (anim_toolbar.handle_box, -1, -1);
} break;
case ID_VIEW_TOOLBAR_ICONS:
{
gtk_toolbar_set_style (GTK_TOOLBAR (main_toolbar.toolbar), GTK_TOOLBAR_ICONS);
gtk_toolbar_set_style (GTK_TOOLBAR (tool_toolbar.toolbar), GTK_TOOLBAR_ICONS);
gtk_toolbar_set_style (GTK_TOOLBAR (anim_toolbar.toolbar), GTK_TOOLBAR_ICONS);
gtk_widget_set_usize (main_toolbar.handle_box, -1, -1);
gtk_widget_set_usize (tool_toolbar.handle_box, -1, -1);
gtk_widget_set_usize (anim_toolbar.handle_box, -1, -1);
} break;
case ID_VIEW_TOOLBAR_TEXT:
{
gtk_toolbar_set_style (GTK_TOOLBAR (main_toolbar.toolbar), GTK_TOOLBAR_TEXT);
gtk_toolbar_set_style (GTK_TOOLBAR (tool_toolbar.toolbar), GTK_TOOLBAR_TEXT);
gtk_toolbar_set_style (GTK_TOOLBAR (anim_toolbar.toolbar), GTK_TOOLBAR_TEXT);
gtk_widget_set_usize (main_toolbar.handle_box, -1, -1);
gtk_widget_set_usize (tool_toolbar.handle_box, -1, -1);
gtk_widget_set_usize (anim_toolbar.handle_box, -1, -1);
} break;
}
}
static gint key_press_event(GtkWidget* widget, GdkEventKey* event, gpointer data)
{
char code = 0;
if (event->keyval < 0x100)
code = gdk_keyval_to_upper(event->keyval);
else
{
switch (event->keyval)
{
case GDK_KP_0: code = '0'; break;
case GDK_KP_1: code = '1'; break;
case GDK_KP_2: code = '2'; break;
case GDK_KP_3: code = '3'; break;
case GDK_KP_4: code = '4'; break;
case GDK_KP_5: code = '5'; break;
case GDK_KP_6: code = '6'; break;
case GDK_KP_7: code = '7'; break;
case GDK_KP_8: code = '8'; break;
case GDK_KP_9: code = '9'; break;
case GDK_KP_Add: code = KEY_PLUS; break;
case GDK_KP_Subtract: code = KEY_MINUS; break;
case GDK_Shift_L: case GDK_Shift_R: code = KEY_SHIFT; break;
case GDK_Control_L: case GDK_Control_R: code = KEY_CONTROL; break;
case GDK_Escape: code = KEY_ESCAPE; break;
case GDK_Tab: code = KEY_TAB; break;
case GDK_Insert: case GDK_KP_Insert: code = KEY_INSERT; break;
case GDK_Delete: case GDK_KP_Delete: code = KEY_DELETE; break;
case GDK_Up: case GDK_KP_Up: code = KEY_UP; break;
case GDK_Down: case GDK_KP_Down: code = KEY_DOWN; break;
case GDK_Left: case GDK_KP_Left: code = KEY_LEFT; break;
case GDK_Right: case GDK_KP_Right: code = KEY_RIGHT; break;
case GDK_Prior: case GDK_KP_Prior: code = KEY_PRIOR; break;
case GDK_Next: case GDK_KP_Next: code = KEY_NEXT; break;
}
}
if ((code >= '0') && (code <= '9') && ((event->state & GDK_CONTROL_MASK) == 0))
{
if (event->state & GDK_SHIFT_MASK)
lcGetActiveProject()->HandleCommand((LC_COMMANDS)(LC_EDIT_MOVEZ_SNAP_0 + code - '0'), 0);
else
lcGetActiveProject()->HandleCommand((LC_COMMANDS)(LC_EDIT_MOVEXY_SNAP_0 + code - '0'), 0);
return TRUE;
}
if (code != 0)
{
if (lcGetActiveProject()->OnKeyDown(code, (event->state & GDK_CONTROL_MASK) != 0,
(event->state & GDK_SHIFT_MASK) != 0))
gtk_signal_emit_stop_by_name (GTK_OBJECT(widget), "key_press_event");
}
return TRUE;
}
static void main_destroy ()
{
gpointer item;
int i = 0;
// Save window position/size
Sys_ProfileSaveInt ("Window", "Width", ((GtkWidget*)(*main_window))->allocation.width);
Sys_ProfileSaveInt ("Window", "Height", ((GtkWidget*)(*main_window))->allocation.height);
// Save toolbar state
Sys_ProfileSaveInt ("Toolbars", "Standard", ((GTK_WIDGET_VISIBLE (main_toolbar.handle_box)) ? 1 : 0));
Sys_ProfileSaveInt ("Toolbars", "Drawing", ((GTK_WIDGET_VISIBLE (tool_toolbar.handle_box)) ? 1 : 0));
Sys_ProfileSaveInt ("Toolbars", "Animation", ((GTK_WIDGET_VISIBLE (anim_toolbar.handle_box)) ? 1 : 0));
Sys_ProfileSaveInt ("Toolbars", "Pieces", (pieces_visible ? 1 : 0));
Sys_ProfileSaveInt ("Toolbars", "Floating", (pieces_floating ? 1 : 0));
if (pieces_parent != NULL)
Sys_ProfileSaveInt ("Toolbars", "PiecesWidth", pieces_frame->allocation.width);
item = gtk_object_get_data (GTK_OBJECT (((GtkWidget*)(*main_window))), "menu_view_toolbar_icons");
if (GTK_CHECK_MENU_ITEM (item)->active)
i = 0;
else
{
item = gtk_object_get_data (GTK_OBJECT (((GtkWidget*)(*main_window))), "menu_view_toolbar_both");
if (GTK_CHECK_MENU_ITEM (item)->active)
i = 1;
else
{
item = gtk_object_get_data (GTK_OBJECT (((GtkWidget*)(*main_window))), "menu_view_toolbar_text");
if (GTK_CHECK_MENU_ITEM (item)->active)
i = 2;
}
}
Sys_ProfileSaveInt ("Toolbars", "Style", i);
gtk_main_quit ();
}
static gint main_quit (GtkWidget *widget, GdkEvent* event, gpointer data)
{
if (!lcGetActiveProject()->SaveModified())
return TRUE;
g_App->Shutdown();
delete g_App;
// save window position
gint x, y;
gdk_window_get_root_origin (((GtkWidget*)(*main_window))->window, &x, &y);
Sys_ProfileSaveInt ("Window", "PositionX", x);
Sys_ProfileSaveInt ("Window", "PositionY", y);
gtk_widget_destroy (((GtkWidget*)(*main_window)));
delete main_window;
main_window = NULL;
return FALSE;
}
static gint pieces_close (GtkWidget *widget, GdkEvent* event, gpointer data)
{
gpointer item;
pieces_visible = FALSE;
item = gtk_object_get_data (GTK_OBJECT (((GtkWidget*)(*main_window))), "menu_view_toolbar_pieces");
gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM (item), FALSE);
item = gtk_object_get_data (GTK_OBJECT (((GtkWidget*)(*main_window))), "menu_view_toolbar_floating");
gtk_widget_set_sensitive (GTK_WIDGET (item), FALSE);
update_window_layout ();
return FALSE;
}
// this function takes care of showing the pieces bar correctly
static void update_window_layout ()
{
// first thing we need to create the widgets
if (drawing_area == NULL)
{
view->CreateFromWindow (&drawing_area);
gtk_widget_set_events (GTK_WIDGET (drawing_area), GDK_EXPOSURE_MASK | GDK_KEY_PRESS_MASK |
GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK | GDK_POINTER_MOTION_MASK |
GDK_POINTER_MOTION_HINT_MASK);
gtk_signal_connect (GTK_OBJECT (drawing_area), "key_press_event",
GTK_SIGNAL_FUNC (key_press_event), NULL);
// set minimum size
gtk_widget_set_usize (GTK_WIDGET (drawing_area), 100, 100);
drawing_frame = gtk_frame_new (NULL);
gtk_widget_show (drawing_frame);
// gtk_container_add (GTK_CONTAINER (hbox), drawing_frame);
gtk_frame_set_shadow_type (GTK_FRAME (drawing_frame), GTK_SHADOW_IN);
gtk_container_add (GTK_CONTAINER (drawing_frame), GTK_WIDGET (drawing_area));
gtk_widget_show (GTK_WIDGET (drawing_area));
// now create the pieces bar
pieces_frame = create_piecebar (((GtkWidget*)(*main_window)), view);
}
else
{
// if the widgets already exist, remove their parents
if (pieces_parent)
pieces_width = pieces_frame->allocation.width;
gtk_container_remove (GTK_CONTAINER (drawing_parent), drawing_frame);
if (pieces_parent != NULL)
gtk_container_remove (GTK_CONTAINER (pieces_parent), pieces_frame);
if (drawing_parent != main_hbox)
gtk_widget_destroy (drawing_parent);
else if (pieces_parent != NULL)
gtk_widget_destroy (pieces_parent);
pieces_parent = NULL;
drawing_parent = NULL;
}
// now add the widgets to their new parents
if (pieces_floating)
{
gtk_box_pack_start (GTK_BOX (main_hbox), drawing_frame, TRUE, TRUE, 0);
drawing_parent = main_hbox;
if (pieces_visible)
{
pieces_parent = gtk_window_new (GTK_WINDOW_TOPLEVEL);
gtk_window_set_transient_for (GTK_WINDOW (pieces_parent), GTK_WINDOW (((GtkWidget*)(*main_window))));
gtk_signal_connect (GTK_OBJECT (pieces_parent), "delete_event",
GTK_SIGNAL_FUNC (pieces_close), NULL);
gtk_signal_connect (GTK_OBJECT (pieces_parent), "destroy",
GTK_SIGNAL_FUNC (gtk_widget_destroy), NULL);
gtk_window_set_title (GTK_WINDOW (pieces_parent), "Pieces");
gtk_window_set_default_size (GTK_WINDOW (pieces_parent), pieces_width, -1);
gtk_container_add (GTK_CONTAINER (pieces_parent), pieces_frame);
gtk_widget_show (pieces_parent);
}
}
else
{
if (pieces_visible)
{
pieces_parent = drawing_parent = gtk_hpaned_new ();
gtk_paned_pack1 (GTK_PANED (drawing_parent), drawing_frame, TRUE, TRUE);
gtk_paned_pack2 (GTK_PANED (pieces_parent), pieces_frame, FALSE, FALSE);
gtk_widget_show (pieces_parent);
gtk_box_pack_start (GTK_BOX (main_hbox), pieces_parent, TRUE, TRUE, 0);
if (pieces_floating == FALSE)
gtk_paned_set_position (GTK_PANED (pieces_parent), ((GtkWidget*)(*main_window))->allocation.width -
pieces_width);
}
else
{
gtk_box_pack_start (GTK_BOX (main_hbox), drawing_frame, TRUE, TRUE, 0);
drawing_parent = main_hbox;
}
}
}
int main (int argc, char* argv[])
{
GtkWidget *vbox;
int x, y;
init_paths (argv[0]);
gtk_set_locale ();
gtk_init (&argc, &argv);
atexit (GL_Shutdown);
// Initialize the application.
g_App = new lcApplication();
main_window = new MainWnd();
char cache_path[LC_MAXPATH];
sprintf(cache_path, "%s/leocad/", g_get_user_cache_dir());
mkdir(cache_path, S_IRWXU | S_IRWXG);
if (!g_App->Initialize(argc, argv, lib_path, cache_path))
return 1;
if (pfnglXQueryExtension (GDK_DISPLAY (), NULL, NULL) != True)
{
g_print("ERROR: OpenGL not supported\n");
return 1;
}
Project* project = lcGetActiveProject();
view = new View(lcGetActiveProject(), NULL);
if (project->GetActiveView())
view->SetCamera(project->GetActiveView()->mCamera, false);
else
view->SetDefaultCamera();
// main_window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
gtk_window_set_title (GTK_WINDOW (((GtkWidget*)(*main_window))), "LeoCAD");
gtk_container_border_width (GTK_CONTAINER (((GtkWidget*)(*main_window))), 0);
gtk_widget_realize (((GtkWidget*)(*main_window)));
// Read window position and size
x = Sys_ProfileLoadInt ("Window", "Width", 600);
y = Sys_ProfileLoadInt ("Window", "Height", 400);
gtk_window_set_default_size (GTK_WINDOW (((GtkWidget*)(*main_window))), x, y);
x = Sys_ProfileLoadInt ("Window", "PositionX", -1);
y = Sys_ProfileLoadInt ("Window", "PositionY", -1);
if ((x != -1 && y != -1) &&
(x < gdk_screen_width () && y < gdk_screen_height ()))
gtk_widget_set_uposition (((GtkWidget*)(*main_window)), x, y);
gtk_signal_connect (GTK_OBJECT (((GtkWidget*)(*main_window))), "delete_event", (GtkSignalFunc) main_quit, NULL);
gtk_signal_connect (GTK_OBJECT (((GtkWidget*)(*main_window))), "destroy", (GtkSignalFunc) main_destroy, NULL);
vbox = gtk_vbox_new (FALSE, 0);
gtk_container_add (GTK_CONTAINER (((GtkWidget*)(*main_window))), vbox);
gtk_widget_show (vbox);
// startup_message ("Creating Main Menu ...");
create_main_menu (GTK_OBJECT (((GtkWidget*)(*main_window))), vbox);
// startup_message ("Creating Toolbars ...");
create_toolbars (((GtkWidget*)(*main_window)), vbox);
main_hbox = gtk_hbox_new (FALSE, 0);
gtk_container_add (GTK_CONTAINER (vbox), main_hbox);
gtk_widget_show (main_hbox);
// load toolbar preferences and update the menu
int show;
ignore_commands = true;
show = Sys_ProfileLoadInt ("Toolbars", "Standard", 1);
if (show)
{
gpointer widget = gtk_object_get_data (GTK_OBJECT (((GtkWidget*)(*main_window))), "menu_view_toolbar_standard");
gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM (widget), TRUE);
}
else
gtk_widget_hide (main_toolbar.handle_box);
show = Sys_ProfileLoadInt ("Toolbars", "Drawing", 1);
if (show)
{
gpointer widget = gtk_object_get_data (GTK_OBJECT (((GtkWidget*)(*main_window))), "menu_view_toolbar_drawing");
gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM (widget), TRUE);
}
else
gtk_widget_hide (tool_toolbar.handle_box);
show = Sys_ProfileLoadInt ("Toolbars", "Animation", 1);
if (show)
{
gpointer widget = gtk_object_get_data (GTK_OBJECT (((GtkWidget*)(*main_window))), "menu_view_toolbar_animation");
gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM (widget), TRUE);
}
else
gtk_widget_hide (anim_toolbar.handle_box);
show = Sys_ProfileLoadInt ("Toolbars", "Pieces", 1);
if (show)
{
gpointer widget = gtk_object_get_data (GTK_OBJECT (((GtkWidget*)(*main_window))), "menu_view_toolbar_pieces");
gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM (widget), TRUE);
pieces_visible = TRUE;
}
else
{
gpointer widget = gtk_object_get_data (GTK_OBJECT (((GtkWidget*)(*main_window))), "menu_view_toolbar_floating");
gtk_widget_set_sensitive (GTK_WIDGET (widget), FALSE);
}
show = Sys_ProfileLoadInt ("Toolbars", "PiecesFloating", 0);
if (show)
{
gpointer widget = gtk_object_get_data (GTK_OBJECT (((GtkWidget*)(*main_window))), "menu_view_toolbar_floating");
gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM (widget), TRUE);
pieces_floating = TRUE;
}
ignore_commands = false;
show = Sys_ProfileLoadInt ("Toolbars", "Style", 0);
gpointer item = NULL;
switch (show)
{
case 0:
item = gtk_object_get_data (GTK_OBJECT (((GtkWidget*)(*main_window))), "menu_view_toolbar_icons");
gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM (item), TRUE);
OnCommand (GTK_WIDGET (item), GINT_TO_POINTER (ID_VIEW_TOOLBAR_ICONS));
break;
case 1:
item = gtk_object_get_data (GTK_OBJECT (((GtkWidget*)(*main_window))), "menu_view_toolbar_both");
gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM (item), TRUE);
OnCommand (GTK_WIDGET (item), GINT_TO_POINTER (ID_VIEW_TOOLBAR_BOTH));
break;
case 2:
item = gtk_object_get_data (GTK_OBJECT (((GtkWidget*)(*main_window))), "menu_view_toolbar_text");
gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM (item), TRUE);
OnCommand (GTK_WIDGET (item), GINT_TO_POINTER (ID_VIEW_TOOLBAR_TEXT));
break;
}
pieces_width = Sys_ProfileLoadInt ("Toolbars", "PiecesWidth", 210);
update_window_layout ();
// increase the reference count to allow changing parents when hiding the pieces bar
gtk_widget_ref (drawing_frame);
gtk_widget_ref (pieces_frame);
create_statusbar (((GtkWidget*)(*main_window)), vbox);
lcGetActiveProject()->UpdateInterface();
main_window->UpdateMRU ();
GdkPixbuf* Pixbuf = gdk_pixbuf_new_from_file(LC_INSTALL_PREFIX"/share/leocad/icon.png", NULL);
if (Pixbuf)
{
gtk_window_set_icon(GTK_WINDOW (((GtkWidget*)(*main_window))), Pixbuf);
}
else
{
#include "pixmaps/icon32.xpm"
GdkPixmap *gdkpixmap;
GdkBitmap *mask;
gdkpixmap = gdk_pixmap_create_from_xpm_d (((GtkWidget*)(*main_window))->window, &mask, &((GtkWidget*)(*main_window))->style->bg[GTK_STATE_NORMAL], (gchar**)icon32);
gdk_window_set_icon (((GtkWidget*)(*main_window))->window, NULL, gdkpixmap, mask);
}
gtk_widget_show (GTK_WIDGET (((GtkWidget*)(*main_window))));
// get the splitter in the correct size, must be done after the widget has been realized
if ((pieces_floating == FALSE) && (pieces_visible == TRUE))
gtk_paned_set_position (GTK_PANED (pieces_parent), ((GtkWidget*)(*main_window))->allocation.width - pieces_width);
GL_EnableVertexBufferObject();
lcPiecesLibrary* Library = lcGetPiecesLibrary();
view->MakeCurrent();
if (lcGetActiveProject()->m_pPieces)
{
for (int PieceIdx = 0; PieceIdx < Library->mPieces.GetSize(); PieceIdx++)
{
lcMesh* Mesh = Library->mPieces[PieceIdx]->mMesh;
if (Mesh)
Mesh->UpdateBuffers();
}
}
PieceInfo* Info = Library->FindPiece("3005", false);
if (!Info)
Info = Library->mPieces[0];
if (Info)
{
lcGetActiveProject()->SetCurrentPiece(Info);
extern PiecePreview* preview;
preview->SetCurrentPiece(Info);
}
gtk_main();
gtk_widget_unref (drawing_frame);
gtk_widget_unref (pieces_frame);
// delete project;
_exit (0); // FIXME !
return 0;
}

View file

@ -1,86 +0,0 @@
#ifndef _MAIN_H_
#define _MAIN_H_
// FIXME: clean up
//extern GtkWidget* main_window;
#include "mainwnd.h"
#include "globals.h"
extern GtkWidget* drawing_area;
extern bool ignore_commands;
void OnCommand(GtkWidget *w, gpointer data);
void OnCommandDirect(GtkWidget *w, gpointer data);
class PieceInfo;
extern PieceInfo *dragged_piece;
extern bool dragging_color;
extern const GtkTargetEntry drag_target_list[];
#define ID_FILE_RECENT1 1
#define ID_FILE_RECENT2 2
#define ID_FILE_RECENT3 3
#define ID_FILE_RECENT4 4
#define ID_FILE_EXIT 5
#define ID_VIEW_CREATE 6
#define ID_VIEW_VIEWPORTS_01 7
#define ID_VIEW_VIEWPORTS_02 8
#define ID_VIEW_VIEWPORTS_03 9
#define ID_VIEW_VIEWPORTS_04 10
#define ID_VIEW_VIEWPORTS_05 11
#define ID_VIEW_VIEWPORTS_06 12
#define ID_VIEW_VIEWPORTS_07 13
#define ID_VIEW_VIEWPORTS_08 14
#define ID_VIEW_VIEWPORTS_09 15
#define ID_VIEW_VIEWPORTS_10 16
#define ID_VIEW_VIEWPORTS_11 17
#define ID_VIEW_VIEWPORTS_12 18
#define ID_VIEW_VIEWPORTS_13 19
#define ID_VIEW_VIEWPORTS_14 20
#define ID_VIEW_TOOLBAR_STANDARD 21
#define ID_VIEW_TOOLBAR_DRAWING 22
#define ID_VIEW_TOOLBAR_ANIMATION 23
#define ID_VIEW_TOOLBAR_MODIFY 24
#define ID_VIEW_TOOLBAR_PIECES 25
#define ID_VIEW_TOOLBAR_FLOATING 26
#define ID_VIEW_TOOLBAR_BOTH 27
#define ID_VIEW_TOOLBAR_ICONS 28
#define ID_VIEW_TOOLBAR_TEXT 29
#define ID_CAMERA_FIRST 1001
#define ID_CAMERA_LAST 1255
#define ID_ACTION_SELECT 100
#define ID_ACTION_INSERT 101
#define ID_ACTION_LIGHT 102
#define ID_ACTION_SPOTLIGHT 103
#define ID_ACTION_CAMERA 104
#define ID_ACTION_MOVE 105
#define ID_ACTION_ROTATE 106
#define ID_ACTION_ERASER 107
#define ID_ACTION_PAINT 108
#define ID_ACTION_ZOOM 109
#define ID_ACTION_ZOOM_REGION 110
#define ID_ACTION_PAN 111
#define ID_ACTION_ROTATE_VIEW 112
#define ID_ACTION_ROLL 113
#define ID_SNAP_A 130
#define ID_SNAP_X 131
#define ID_SNAP_Y 132
#define ID_SNAP_Z 133
#define ID_SNAP_ALL 134
#define ID_SNAP_NONE 135
#define ID_SNAP_ON 136
#define ID_LOCK_X 140
#define ID_LOCK_Y 141
#define ID_LOCK_Z 142
#define ID_LOCK_NONE 143
#define ID_LOCK_ON 144
#endif

View file

@ -1,282 +0,0 @@
#include "lc_global.h"
#include <gtk/gtk.h>
#include <stdio.h>
#include "typedefs.h"
#include "main.h"
#include "gtkmisc.h"
#include "mainwnd.h"
void create_main_menu(GtkObject *window, GtkWidget *vbox)
{
#include "pixmaps/st-new.xpm"
#include "pixmaps/st-open.xpm"
#include "pixmaps/st-save.xpm"
#include "pixmaps/photo.xpm"
#include "pixmaps/info.xpm"
#include "pixmaps/st-undo.xpm"
#include "pixmaps/st-redo.xpm"
#include "pixmaps/st-cut.xpm"
#include "pixmaps/st-copy.xpm"
#include "pixmaps/st-paste.xpm"
GtkWidget *handle_box, *menu_bar, *menu, *menu_in_menu, *item;
GtkAccelGroup *accel;
accel = gtk_accel_group_new();
gtk_window_add_accel_group(GTK_WINDOW(window), accel);
handle_box = gtk_handle_box_new();
gtk_box_pack_start(GTK_BOX(vbox), handle_box, FALSE, FALSE, 0);
gtk_widget_show(handle_box);
menu_bar = gtk_menu_bar_new();
gtk_container_add(GTK_CONTAINER(handle_box), menu_bar);
gtk_widget_show(menu_bar);
// File menu
menu = create_sub_menu(menu_bar, "_File", accel);
menu_tearoff(menu);
create_pixmap_menu_item(menu, "_New", st_new, accel, GTK_SIGNAL_FUNC(OnCommandDirect), window, LC_FILE_NEW, "menu_file_new");
create_pixmap_menu_item(menu, "_Open...", st_open, accel, GTK_SIGNAL_FUNC(OnCommandDirect), window, LC_FILE_OPEN, "menu_file_open");
create_menu_item(menu, "_Merge...", accel, GTK_SIGNAL_FUNC(OnCommandDirect), window, LC_FILE_MERGE, "menu_file_merge");
menu_separator(menu);
create_pixmap_menu_item(menu, "_Save", st_save, accel, GTK_SIGNAL_FUNC(OnCommandDirect), window, LC_FILE_SAVE, "menu_file_save");
create_menu_item(menu, "Save _As...", accel, GTK_SIGNAL_FUNC(OnCommandDirect), window, LC_FILE_SAVEAS, "menu_file_saveas");
create_pixmap_menu_item(menu, "Save Pic_ture...", photo, accel, GTK_SIGNAL_FUNC(OnCommandDirect), window, LC_FILE_PICTURE, "menu_file_picture");
menu_in_menu = create_menu_in_menu(menu, "Ex_port", accel);
create_menu_item(menu_in_menu, "_BrickLink...", accel, GTK_SIGNAL_FUNC(OnCommandDirect), window, LC_FILE_BRICKLINK, "menu_file_bricklink");
create_menu_item(menu_in_menu, "_HTML...", accel, GTK_SIGNAL_FUNC(OnCommandDirect), window, LC_FILE_HTML, "menu_file_html");
create_menu_item(menu_in_menu, "_POV-Ray...", accel, GTK_SIGNAL_FUNC(OnCommandDirect), window, LC_FILE_POVRAY, "menu_file_povray");
create_menu_item(menu_in_menu, "_Wavefront...", accel, GTK_SIGNAL_FUNC(OnCommandDirect), window, LC_FILE_WAVEFRONT, "menu_file_wavefront");
menu_separator(menu);
create_pixmap_menu_item(menu, "Propert_ies...", info, accel, GTK_SIGNAL_FUNC(OnCommandDirect), window, LC_FILE_PROPERTIES, "menu_file_properties");
create_menu_item(menu, "Pieces _Library Manager...", accel, GTK_SIGNAL_FUNC(OnCommandDirect), window, LC_FILE_LIBRARY, "menu_file_library");
menu_separator(menu);
BaseMenuItem base;
base.accel = accel;
base.widget = create_menu_item(menu, "1", accel, GTK_SIGNAL_FUNC(OnCommand), window, ID_FILE_RECENT1, "menu_file_recent1");
main_window->SetMenuItem(LC_MAINWND_RECENT1, &base);
base.widget = create_menu_item(menu, "2", accel, GTK_SIGNAL_FUNC(OnCommand), window, ID_FILE_RECENT2, "menu_file_recent2");
main_window->SetMenuItem(LC_MAINWND_RECENT2, &base);
base.widget = create_menu_item(menu, "3", accel, GTK_SIGNAL_FUNC(OnCommand), window, ID_FILE_RECENT3, "menu_file_recent3");
main_window->SetMenuItem(LC_MAINWND_RECENT3, &base);
base.widget = create_menu_item(menu, "4", accel, GTK_SIGNAL_FUNC(OnCommand), window, ID_FILE_RECENT4, "menu_file_recent4");
main_window->SetMenuItem(LC_MAINWND_RECENT4, &base);
gtk_object_set_data(window, "file_menu_accel", accel);
menu_separator(menu);
create_menu_item(menu, "E_xit...", accel, GTK_SIGNAL_FUNC(OnCommand),
window, ID_FILE_EXIT, "menu_file_exit");
// Edit menu
menu = create_sub_menu(menu_bar, "_Edit", accel);
menu_tearoff(menu);
create_pixmap_menu_item(menu, "_Undo", st_undo, accel, GTK_SIGNAL_FUNC(OnCommandDirect), window, LC_EDIT_UNDO, "menu_edit_undo");
create_pixmap_menu_item(menu, "_Redo", st_redo, accel, GTK_SIGNAL_FUNC(OnCommandDirect), window, LC_EDIT_REDO, "menu_edit_redo");
menu_separator(menu);
create_pixmap_menu_item(menu, "Cu_t", st_cut, accel, GTK_SIGNAL_FUNC(OnCommandDirect), window, LC_EDIT_CUT, "menu_edit_cut");
create_pixmap_menu_item(menu, "_Copy", st_copy, accel, GTK_SIGNAL_FUNC(OnCommandDirect), window, LC_EDIT_COPY, "menu_edit_copy");
create_pixmap_menu_item(menu, "_Paste", st_paste, accel, GTK_SIGNAL_FUNC(OnCommandDirect), window, LC_EDIT_PASTE, "menu_edit_paste");
menu_separator(menu);
create_menu_item(menu, "Select _All", accel, GTK_SIGNAL_FUNC(OnCommandDirect), window, LC_EDIT_SELECT_ALL, "menu_edit_select_all");
create_menu_item(menu, "Select _None", accel, GTK_SIGNAL_FUNC(OnCommandDirect), window, LC_EDIT_SELECT_NONE, "menu_edit_select_none");
create_menu_item(menu, "Select _Invert", accel, GTK_SIGNAL_FUNC(OnCommandDirect), window, LC_EDIT_SELECT_INVERT, "menu_edit_select_invert");
create_menu_item(menu, "_Select by Name...", accel, GTK_SIGNAL_FUNC(OnCommandDirect), window, LC_EDIT_SELECT_BYNAME, "menu_edit_select_byname");
// View menu
menu = create_sub_menu(menu_bar, "_View", accel);
menu_tearoff(menu);
create_menu_item(menu, "_Preferences...", accel, GTK_SIGNAL_FUNC(OnCommandDirect), window, LC_VIEW_PREFERENCES, "menu_view_preferences");
menu_separator(menu);
create_menu_item(menu, "Zoom _In", accel, GTK_SIGNAL_FUNC(OnCommandDirect), window, LC_VIEW_ZOOMIN, "menu_view_zoomin");
create_menu_item(menu, "Zoom _Out", accel, GTK_SIGNAL_FUNC(OnCommandDirect), window, LC_VIEW_ZOOMOUT, "menu_view_zoomout");
create_menu_item(menu, "Zoom E_xtents", accel, GTK_SIGNAL_FUNC(OnCommandDirect), window, LC_VIEW_ZOOMEXTENTS, "menu_view_zoomextents");
menu_in_menu = create_menu_in_menu(menu, "_Viewpoints", accel);
create_menu_item(menu_in_menu, "Front", accel, GTK_SIGNAL_FUNC(OnCommandDirect), window, LC_VIEW_VIEWPOINT_FRONT, "menu_view_viewpoint_front");
create_menu_item(menu_in_menu, "Back", accel, GTK_SIGNAL_FUNC(OnCommandDirect), window, LC_VIEW_VIEWPOINT_BACK, "menu_view_viewpoint_back");
create_menu_item(menu_in_menu, "Top", accel, GTK_SIGNAL_FUNC(OnCommandDirect), window, LC_VIEW_VIEWPOINT_TOP, "menu_view_viewpoint_top");
create_menu_item(menu_in_menu, "Bottom", accel, GTK_SIGNAL_FUNC(OnCommandDirect), window, LC_VIEW_VIEWPOINT_BOTTOM, "menu_view_viewpoint_bottom");
create_menu_item(menu_in_menu, "Left", accel, GTK_SIGNAL_FUNC(OnCommandDirect), window, LC_VIEW_VIEWPOINT_LEFT, "menu_view_viewpoint_left");
create_menu_item(menu_in_menu, "Right", accel, GTK_SIGNAL_FUNC(OnCommandDirect), window, LC_VIEW_VIEWPOINT_RIGHT, "menu_view_viewpoint_right");
create_menu_item(menu_in_menu, "Home", accel, GTK_SIGNAL_FUNC(OnCommandDirect), window, LC_VIEW_VIEWPOINT_HOME, "menu_view_viewpoint_home");
menu_in_menu = create_menu_in_menu(menu, "_Cameras", accel);
gtk_object_set_data(window, "cameras_menu", menu_in_menu);
create_menu_item(menu_in_menu, "_Reset", accel, GTK_SIGNAL_FUNC(OnCommandDirect), window, LC_VIEW_CAMERA_RESET, "menu_cameras_reset");
menu_in_menu = create_menu_in_menu(menu, "S_tep", accel);
create_menu_item(menu_in_menu, "Fi_rst", accel, GTK_SIGNAL_FUNC(OnCommandDirect), window, LC_VIEW_STEP_FIRST, "menu_view_step_first");
create_menu_item(menu_in_menu, "Pre_vious", accel, GTK_SIGNAL_FUNC(OnCommandDirect), window, LC_VIEW_STEP_PREVIOUS, "menu_view_step_previous");
create_menu_item(menu_in_menu, "Ne_xt", accel, GTK_SIGNAL_FUNC(OnCommandDirect), window, LC_VIEW_STEP_NEXT, "menu_view_step_next");
create_menu_item(menu_in_menu, "_Last", accel, GTK_SIGNAL_FUNC(OnCommandDirect), window, LC_VIEW_STEP_LAST, "menu_view_step_last");
menu_separator(menu_in_menu);
create_menu_item(menu_in_menu, "_Insert", accel, GTK_SIGNAL_FUNC(OnCommandDirect), window, LC_VIEW_STEP_INSERT, "menu_view_step_insert");
create_menu_item(menu_in_menu, "_Delete", accel, GTK_SIGNAL_FUNC(OnCommandDirect), window, LC_VIEW_STEP_DELETE, "menu_view_step_delete");
// create_menu_item(menu, "_Create", accel, GTK_SIGNAL_FUNC(OnCommand), window, ID_VIEW_CREATE, "menu_view_create");
menu_separator(menu);
menu_in_menu = create_menu_in_menu(menu, "Tool_bars", accel);
create_check_menu_item(menu_in_menu, "S_tandard", accel, GTK_SIGNAL_FUNC(OnCommand), window, ID_VIEW_TOOLBAR_STANDARD, "menu_view_toolbar_standard");
create_check_menu_item(menu_in_menu, "Dra_wing", accel, GTK_SIGNAL_FUNC(OnCommand), window, ID_VIEW_TOOLBAR_DRAWING, "menu_view_toolbar_drawing");
create_check_menu_item(menu_in_menu, "Ani_mation", accel, GTK_SIGNAL_FUNC(OnCommand), window, ID_VIEW_TOOLBAR_ANIMATION, "menu_view_toolbar_animation");
// create_check_menu_item(menu_in_menu, "Mo_dify", accel, GTK_SIGNAL_FUNC(OnCommand), window, ID_VIEW_TOOLBAR_MODIFY, "menu_view_toolbar_modify");
create_check_menu_item(menu_in_menu, "_Pieces", accel, GTK_SIGNAL_FUNC(OnCommand), window, ID_VIEW_TOOLBAR_PIECES, "menu_view_toolbar_pieces");
menu_separator(menu_in_menu);
create_check_menu_item(menu_in_menu, "_Floating Pieces", accel, GTK_SIGNAL_FUNC(OnCommand),
window, ID_VIEW_TOOLBAR_FLOATING, "menu_view_toolbar_floating");
item = create_radio_menu_item(menu_in_menu, NULL, "Icons _and Text", accel, GTK_SIGNAL_FUNC(OnCommand),
window, ID_VIEW_TOOLBAR_BOTH, "menu_view_toolbar_both");
item = create_radio_menu_item(menu_in_menu, item, "_Icons only", accel, GTK_SIGNAL_FUNC(OnCommand),
window, ID_VIEW_TOOLBAR_ICONS, "menu_view_toolbar_icons");
item = create_radio_menu_item(menu_in_menu, item, "Te_xt only", accel, GTK_SIGNAL_FUNC(OnCommand),
window, ID_VIEW_TOOLBAR_TEXT, "menu_view_toolbar_text");
// Piece menu
menu = create_sub_menu(menu_bar, "_Piece", accel);
menu_tearoff(menu);
create_menu_item(menu, "_Insert", accel, GTK_SIGNAL_FUNC(OnCommandDirect),
window, LC_PIECE_INSERT, "menu_piece_insert");
create_menu_item(menu, "De_lete", accel, GTK_SIGNAL_FUNC(OnCommandDirect),
window, LC_PIECE_DELETE, "menu_piece_delete");
create_menu_item(menu, "Ar_ray...", accel, GTK_SIGNAL_FUNC(OnCommandDirect),
window, LC_PIECE_ARRAY, "menu_piece_array");
create_menu_item(menu, "Minifig Wi_zard...", accel, GTK_SIGNAL_FUNC(OnCommandDirect),
window, LC_PIECE_MINIFIG, "menu_piece_minifig");
create_menu_item(menu, "_Copy Keys", accel, GTK_SIGNAL_FUNC(OnCommandDirect),
window, LC_PIECE_COPYKEYS, "menu_piece_copykeys");
menu_separator(menu);
create_menu_item(menu, "_Group", accel, GTK_SIGNAL_FUNC(OnCommandDirect), window, LC_PIECE_GROUP, "menu_piece_group");
create_menu_item(menu, "_Ungroup", accel, GTK_SIGNAL_FUNC(OnCommandDirect), window, LC_PIECE_UNGROUP, "menu_piece_ungroup");
create_menu_item(menu, "Re_move from Group", accel, GTK_SIGNAL_FUNC(OnCommandDirect), window, LC_PIECE_GROUP_REMOVE, "menu_piece_group_remove");
create_menu_item(menu, "A_dd to Group", accel, GTK_SIGNAL_FUNC(OnCommandDirect), window, LC_PIECE_GROUP_ADD, "menu_piece_group_add");
create_menu_item(menu, "Edi_t Groups...", accel, GTK_SIGNAL_FUNC(OnCommandDirect), window, LC_PIECE_GROUP_EDIT, "menu_piece_group_edit");
menu_separator(menu);
create_menu_item(menu, "Hide _Selected", accel, GTK_SIGNAL_FUNC(OnCommandDirect), window, LC_PIECE_HIDE_SELECTED, "menu_piece_hide_selected");
create_menu_item(menu, "Hide U_nselected", accel, GTK_SIGNAL_FUNC(OnCommandDirect), window, LC_PIECE_HIDE_UNSELECTED, "menu_piece_hide_unselected");
create_menu_item(menu, "Unhide _All", accel, GTK_SIGNAL_FUNC(OnCommandDirect), window, LC_PIECE_UNHIDE_ALL, "menu_piece_unhide_all");
menu = create_sub_menu(menu_bar, "_Help", accel);
menu_tearoff(menu);
create_menu_item(menu, "_About...", accel, GTK_SIGNAL_FUNC(OnCommandDirect), window, LC_HELP_ABOUT, "menu_help_about");
// TODO: read accelerators from a file
item = GTK_WIDGET(gtk_object_get_data(window, "menu_file_new"));
gtk_widget_add_accelerator(item, "activate", accel, 'N', GDK_CONTROL_MASK, GTK_ACCEL_VISIBLE);
item = GTK_WIDGET(gtk_object_get_data(window, "menu_file_open"));
gtk_widget_add_accelerator(item, "activate", accel, 'O', GDK_CONTROL_MASK, GTK_ACCEL_VISIBLE);
item = GTK_WIDGET(gtk_object_get_data(window, "menu_file_save"));
gtk_widget_add_accelerator(item, "activate", accel, 'S', GDK_CONTROL_MASK, GTK_ACCEL_VISIBLE);
item = GTK_WIDGET(gtk_object_get_data(window, "menu_file_exit"));
gtk_widget_add_accelerator(item, "activate", accel, 'Q', GDK_CONTROL_MASK, GTK_ACCEL_VISIBLE);
item = GTK_WIDGET(gtk_object_get_data(window, "menu_edit_undo"));
gtk_widget_add_accelerator(item, "activate", accel, 'Z', GDK_CONTROL_MASK, GTK_ACCEL_VISIBLE);
item = GTK_WIDGET(gtk_object_get_data(window, "menu_edit_redo"));
gtk_widget_add_accelerator(item, "activate", accel, 'Y', GDK_CONTROL_MASK, GTK_ACCEL_VISIBLE);
item = GTK_WIDGET(gtk_object_get_data(window, "menu_edit_cut"));
gtk_widget_add_accelerator(item, "activate", accel, 'X', GDK_CONTROL_MASK, GTK_ACCEL_VISIBLE);
item = GTK_WIDGET(gtk_object_get_data(window, "menu_edit_copy"));
gtk_widget_add_accelerator(item, "activate", accel, 'C', GDK_CONTROL_MASK, GTK_ACCEL_VISIBLE);
item = GTK_WIDGET(gtk_object_get_data(window, "menu_edit_paste"));
gtk_widget_add_accelerator(item, "activate", accel, 'V', GDK_CONTROL_MASK, GTK_ACCEL_VISIBLE);
item = GTK_WIDGET(gtk_object_get_data(window, "menu_piece_array"));
gtk_widget_add_accelerator(item, "activate", accel, 'R', GDK_CONTROL_MASK, GTK_ACCEL_VISIBLE);
item = GTK_WIDGET(gtk_object_get_data(window, "menu_piece_group"));
gtk_widget_add_accelerator(item, "activate", accel, 'G', GDK_CONTROL_MASK, GTK_ACCEL_VISIBLE);
item = GTK_WIDGET(gtk_object_get_data(window, "menu_piece_ungroup"));
gtk_widget_add_accelerator(item, "activate", accel, 'U', GDK_CONTROL_MASK, GTK_ACCEL_VISIBLE);
item = GTK_WIDGET(gtk_object_get_data(window, "menu_piece_group_remove"));
gtk_widget_add_accelerator(item, "activate", accel, 'M', GDK_CONTROL_MASK, GTK_ACCEL_VISIBLE);
item = GTK_WIDGET(gtk_object_get_data(window, "menu_piece_group_add"));
gtk_widget_add_accelerator(item, "activate", accel, 'D', GDK_CONTROL_MASK, GTK_ACCEL_VISIBLE);
}
GtkWidget* create_snap_menu()
{
GtkWidget* menu;
GtkWidget* menu_item;
menu = gtk_menu_new();
menu_item = gtk_check_menu_item_new_with_mnemonic("Snap _X");
gtk_object_set_data(GTK_OBJECT(menu), "snap_x", menu_item);
gtk_menu_shell_append(GTK_MENU_SHELL(menu), menu_item);
gtk_signal_connect(GTK_OBJECT(menu_item), "activate", GTK_SIGNAL_FUNC(OnCommand), GINT_TO_POINTER(ID_SNAP_X));
gtk_widget_show(menu_item);
menu_item = gtk_check_menu_item_new_with_mnemonic("Snap _Y");
gtk_object_set_data(GTK_OBJECT(menu), "snap_y", menu_item);
gtk_menu_shell_append(GTK_MENU_SHELL(menu), menu_item);
gtk_signal_connect(GTK_OBJECT(menu_item), "activate", GTK_SIGNAL_FUNC(OnCommand), GINT_TO_POINTER(ID_SNAP_Y));
gtk_widget_show(menu_item);
menu_item = gtk_check_menu_item_new_with_mnemonic("Snap _Z");
gtk_object_set_data(GTK_OBJECT(menu), "snap_z", menu_item);
gtk_menu_shell_append(GTK_MENU_SHELL(menu), menu_item);
gtk_signal_connect(GTK_OBJECT(menu_item), "activate", GTK_SIGNAL_FUNC(OnCommand), GINT_TO_POINTER(ID_SNAP_Z));
gtk_widget_show(menu_item);
menu_item = gtk_menu_item_new_with_mnemonic("Snap _None");
gtk_menu_shell_append(GTK_MENU_SHELL(menu), menu_item);
gtk_signal_connect(GTK_OBJECT(menu_item), "activate", GTK_SIGNAL_FUNC(OnCommand), GINT_TO_POINTER(ID_SNAP_NONE));
gtk_widget_show(menu_item);
menu_item = gtk_menu_item_new_with_mnemonic("Snap _All");
gtk_menu_shell_append(GTK_MENU_SHELL(menu), menu_item);
gtk_signal_connect(GTK_OBJECT(menu_item), "activate", GTK_SIGNAL_FUNC(OnCommand), GINT_TO_POINTER(ID_SNAP_ALL));
gtk_widget_show(menu_item);
return menu;
}
GtkWidget* create_lock_menu()
{
GtkWidget* menu;
GtkWidget* menu_item;
menu = gtk_menu_new();
menu_item = gtk_check_menu_item_new_with_mnemonic("Lock _X");
gtk_object_set_data(GTK_OBJECT(menu), "lock_x", menu_item);
gtk_menu_shell_append(GTK_MENU_SHELL(menu), menu_item);
gtk_signal_connect(GTK_OBJECT(menu_item), "activate", GTK_SIGNAL_FUNC(OnCommand), GINT_TO_POINTER(ID_LOCK_X));
gtk_widget_show(menu_item);
menu_item = gtk_check_menu_item_new_with_mnemonic("Lock _Y");
gtk_object_set_data(GTK_OBJECT(menu), "lock_y", menu_item);
gtk_menu_shell_append(GTK_MENU_SHELL(menu), menu_item);
gtk_signal_connect(GTK_OBJECT(menu_item), "activate", GTK_SIGNAL_FUNC(OnCommand), GINT_TO_POINTER(ID_LOCK_Y));
gtk_widget_show(menu_item);
menu_item = gtk_check_menu_item_new_with_mnemonic("Lock _Z");
gtk_object_set_data(GTK_OBJECT(menu), "lock_z", menu_item);
gtk_menu_shell_append(GTK_MENU_SHELL(menu), menu_item);
gtk_signal_connect(GTK_OBJECT(menu_item), "activate", GTK_SIGNAL_FUNC(OnCommand), GINT_TO_POINTER(ID_LOCK_Z));
gtk_widget_show(menu_item);
menu_item = gtk_menu_item_new_with_mnemonic("Unlock All");
gtk_menu_shell_append(GTK_MENU_SHELL(menu), menu_item);
gtk_signal_connect(GTK_OBJECT(menu_item), "activate", GTK_SIGNAL_FUNC(OnCommand), GINT_TO_POINTER(ID_LOCK_NONE));
gtk_widget_show(menu_item);
return menu;
}

View file

@ -1,5 +0,0 @@
SRC += linux/profile.cpp \
linux/dialogs.cpp linux/dlgpiece.cpp linux/dlgfile.cpp \
linux/gtktools.cpp linux/main.cpp linux/menu.cpp \
linux/system.cpp linux/toolbar.cpp linux/gtkmisc.cpp \
linux/linux_gl.cpp linux/basewnd.cpp linux/glwindow.cpp linux/libdlg.cpp

View file

@ -1,25 +0,0 @@
/* XPM */
static const char*ac_brick[] = {
/* columns rows colors chars-per-pixel */
"16 15 4 1",
" c #00007f",
". c Gray50",
"o c Gray75",
"X c None",
/* pixels */
"XXXXXXXXXXXXXXXX",
"XXXXXXXXXXXXXXXX",
"XXXXXX XXXXXX",
"XXXXX oo XXX",
"XXXX o o XXX",
"XXX oooooo . XXX",
"XX .. XXX",
"XX oooooo .. XXX",
"XX oooooo .. XXX",
"XX oooooo .. XXX",
"XX oooooo .. XXX",
"XX oooooo . XXXX",
"XX oooooo XXXXX",
"XX XXXXXX",
"XXXXXXXXXXXXXXXX"
};

View file

@ -1,24 +0,0 @@
/* XPM */
static const char* ac_cam[] = {
"16 15 6 1",
". c None",
"+ c #7F7F7F",
"@ c #000000",
"# c #FFFFFF",
"$ c #BFBFBF",
"% c #FF0000",
"..+@+...+@+.....",
".@##$@.@##$@....",
"+##@#$@##@#$@...",
"@#@@@#@#@@@#@...",
"+$#@#$@$#@#$@...",
".@$#$@$@$#$@@..@",
"..@@@$$$@@@$+@@@",
"..@$$+$+$+$++$#@",
"..@+%%++++++@+$@",
"..@@@@@@@@@@@@@@",
"...@@@@@@@@@..@@",
"......@+@......@",
"......@+@.......",
"......@@@.......",
"................"};

View file

@ -1,26 +0,0 @@
/* XPM */
static const char*ac_erase[] = {
/* columns rows colors chars-per-pixel */
"16 15 5 1",
" c Gray0",
". c Gray50",
"X c None",
"O c Gray75",
"o c Gray100",
/* pixels */
"XXXXXXXXXXXXXXXX",
"XXXXXXXXXXXXXXXX",
"XXXXXXXX. ..X",
"XXXXXXX oooooO X",
"XXXXXX oooooo X",
"XXXXX oooooo . X",
"XXXX oooooo .. X",
"XXX oooooo .. XX",
"XX oooooo .. XXX",
"X OOOOOO .. XXXX",
"X OOOOOO . XXXXX",
"X OOOOOO XXXXXX",
"XX .XXXXXXX",
"XXXXXXXXXXXXXXXX",
"XXXXXXXXXXXXXXXX"
};

View file

@ -1,23 +0,0 @@
/* XPM */
static const char* ac_light[] = {
"16 15 5 1",
". c None",
"+ c #000000",
"@ c #7F7F7F",
"# c #FFFFFF",
"$ c #BFBFBF",
".....++++++.....",
"...@+#####$+@...",
"...+#######$+...",
"..+#########$+..",
"..+########$#+..",
"..+#######$#$+..",
"..+#$####$#$#+..",
"..@+#$$#$#$#+@..",
"...@+##$#$#+@...",
"....+@##$#@+....",
".....++++++.....",
".....+$#@@+.....",
".....@++++@.....",
".....+$#@@+.....",
"......++++......"};

Some files were not shown because too many files have changed in this diff Show more