mirror of
https://github.com/leozide/leocad
synced 2024-12-25 21:58:23 +01:00
Merged qtest branch into trunk.
This commit is contained in:
parent
3bb6b098c8
commit
f11c97777a
307 changed files with 25195 additions and 26292 deletions
|
@ -1,2 +0,0 @@
|
|||
all:
|
||||
gmake ${.MAKEFLAGS} ${.TARGETS}
|
204
Makefile
204
Makefile
|
@ -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 '*/.#*')
|
||||
|
|
@ -1 +0,0 @@
|
|||
include ../generic.mk
|
0
common/array.cpp
Executable file → Normal file
0
common/array.cpp
Executable file → Normal file
15
common/array.h
Executable file → Normal file
15
common/array.h
Executable file → Normal 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]; }
|
||||
|
||||
|
|
212
common/basewnd.h
212
common/basewnd.h
|
@ -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_
|
||||
|
|
|
@ -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)));
|
||||
|
||||
|
|
|
@ -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
0
common/curve.cpp
Executable file → Normal file
4
common/curve.h
Executable file → Normal file
4
common/curve.h
Executable file → Normal 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_
|
||||
|
|
153
common/defines.h
153
common/defines.h
|
@ -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_
|
||||
|
|
|
@ -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;
|
|
@ -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_
|
|
@ -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];
|
||||
};
|
||||
|
||||
|
|
|
@ -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;
|
||||
}
|
|
@ -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
|
482
common/image.cpp
482
common/image.cpp
|
@ -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
|
||||
|
|
|
@ -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_
|
||||
|
|
|
@ -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;
|
||||
}
|
|
@ -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_
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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
152
common/lc_category.cpp
Normal 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
25
common/lc_category.h
Normal 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_
|
1180
common/lc_colors.cpp
1180
common/lc_colors.cpp
File diff suppressed because it is too large
Load diff
|
@ -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
1206
common/lc_commands.cpp
Normal file
File diff suppressed because it is too large
Load diff
196
common/lc_commands.h
Normal file
196
common/lc_commands.h
Normal 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
1
common/lc_global.cpp
Normal file
|
@ -0,0 +1 @@
|
|||
#include "lc_global.h"
|
|
@ -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
83
common/lc_glwidget.h
Normal 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
|
@ -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_
|
||||
|
|
3067
common/lc_math.h
3067
common/lc_math.h
File diff suppressed because it is too large
Load diff
|
@ -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);
|
||||
}
|
||||
|
|
338
common/lc_mesh.h
338
common/lc_mesh.h
|
@ -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
95
common/lc_profile.cpp
Normal 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
103
common/lc_profile.h
Normal 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
110
common/lc_shortcuts.cpp
Normal 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
25
common/lc_shortcuts.h
Normal 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_
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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
|
@ -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_
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
|
||||
|
|
|
@ -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_
|
||||
|
|
|
@ -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);
|
||||
}
|
|
@ -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_
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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
4
common/object.cpp
Executable file → Normal 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
0
common/object.h
Executable file → Normal file
1221
common/opengl.cpp
Executable file → Normal 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
1303
common/opengl.h
Executable file → Normal file
File diff suppressed because it is too large
Load diff
|
@ -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)
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -96,7 +96,7 @@ void PieceInfo::Load()
|
|||
lcGetPiecesLibrary()->GeneratePiece(this);
|
||||
else
|
||||
lcGetPiecesLibrary()->LoadPiece(this);
|
||||
}
|
||||
}
|
||||
|
||||
void PieceInfo::Unload()
|
||||
{
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
|
|
|
@ -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; }
|
||||
|
|
3885
common/project.cpp
3885
common/project.cpp
File diff suppressed because it is too large
Load diff
197
common/project.h
197
common/project.h
|
@ -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_
|
||||
|
|
662
common/quant.cpp
662
common/quant.cpp
|
@ -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;
|
||||
}
|
|
@ -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
110
common/system.h
Executable file → Normal 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_
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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:
|
||||
|
|
|
@ -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
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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
15
docs/CREDITS.txt
Normal 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>
|
|
@ -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'
|
||||
|
|
@ -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
213
leocad.pro
Normal 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
66
leocad.qrc
Normal 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>
|
|
@ -1 +0,0 @@
|
|||
include ../generic.mk
|
|
@ -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);
|
||||
}
|
||||
|
2840
linux/dialogs.cpp
2840
linux/dialogs.cpp
File diff suppressed because it is too large
Load diff
|
@ -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_
|
||||
|
|
@ -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;
|
||||
}
|
|
@ -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;
|
||||
}
|
||||
|
|
@ -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;
|
||||
}
|
||||
|
|
@ -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;
|
||||
}
|
|
@ -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_
|
|
@ -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);
|
||||
}
|
||||
|
|
@ -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_
|
||||
|
|
@ -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_
|
||||
|
346
linux/libdlg.cpp
346
linux/libdlg.cpp
|
@ -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;
|
||||
}
|
||||
*/
|
|
@ -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_
|
|
@ -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;
|
||||
}
|
114
linux/linux_gl.h
114
linux/linux_gl.h
|
@ -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_
|
783
linux/main.cpp
783
linux/main.cpp
|
@ -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;
|
||||
}
|
86
linux/main.h
86
linux/main.h
|
@ -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
|
||||
|
||||
|
||||
|
282
linux/menu.cpp
282
linux/menu.cpp
|
@ -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;
|
||||
}
|
||||
|
|
@ -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
|
|
@ -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"
|
||||
};
|
|
@ -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",
|
||||
"..+@+...+@+.....",
|
||||
".@##$@.@##$@....",
|
||||
"+##@#$@##@#$@...",
|
||||
"@#@@@#@#@@@#@...",
|
||||
"+$#@#$@$#@#$@...",
|
||||
".@$#$@$@$#$@@..@",
|
||||
"..@@@$$$@@@$+@@@",
|
||||
"..@$$+$+$+$++$#@",
|
||||
"..@+%%++++++@+$@",
|
||||
"..@@@@@@@@@@@@@@",
|
||||
"...@@@@@@@@@..@@",
|
||||
"......@+@......@",
|
||||
"......@+@.......",
|
||||
"......@@@.......",
|
||||
"................"};
|
|
@ -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"
|
||||
};
|
|
@ -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
Loading…
Reference in a new issue