#include "pch.h" #include "AppSettings.h" #include "niutils.h" #include <io.h> #include "obj/NiControllerSequence.h" using namespace Niflib; #define KFEXPORT_CLASS_ID Class_ID(0xa57ff0a4, 0xa0374ffc) static LPCTSTR KfExportSection = TEXT("KfExport"); class KfExport : public SceneExport { public: static HWND hParams; int mDlgResult; TSTR iniFileName; TSTR shortDescription; TSTR fileVersion; int ExtCount(); // Number of extensions supported const TCHAR *Ext(int n); // Extension #n (i.e. "3DS") const TCHAR *LongDesc(); // Long ASCII description (i.e. "Autodesk 3D Studio File") const TCHAR *ShortDesc(); // Short ASCII description (i.e. "3D Studio") const TCHAR *AuthorName(); // ASCII Author name const TCHAR *CopyrightMessage(); // ASCII Copyright message const TCHAR *OtherMessage1(); // Other message #1 const TCHAR *OtherMessage2(); // Other message #2 unsigned int Version(); // Version number * 100 (i.e. v3.01 = 301) void ShowAbout(HWND hWnd); // Show DLL's "About..." box BOOL SupportsOptions(int ext, DWORD options); int DoExport(const TCHAR *name,ExpInterface *ei,Interface *i, BOOL suppressPrompts=FALSE, DWORD options=0); KfExport(); ~KfExport(); }; class KfExportClassDesc : public ClassDesc2 { public: int IsPublic() { return TRUE; } void *Create(BOOL loading = FALSE) { return new KfExport(); } const TCHAR *ClassName() { return GetString(IDS_KF_CLASS_NAME); } SClass_ID SuperClassID() { return SCENE_EXPORT_CLASS_ID; } Class_ID ClassID() { return KFEXPORT_CLASS_ID; } const TCHAR *Category() { return GetString(IDS_CATEGORY); } const TCHAR *InternalName() { return _T("_KfExport"); } // returns fixed parsable name (scripter-visible name) HINSTANCE HInstance() { return hInstance; } // returns owning module handle }; static KfExportClassDesc KfExportDesc; ClassDesc2* GetKfExportDesc() { return &KfExportDesc; } static BOOL CALLBACK KfExportOptionsDlgProc(HWND hWnd,UINT message,WPARAM wParam,LPARAM lParam) { static KfExport *imp = NULL; switch (message) { case WM_INITDIALOG: { imp = (KfExport *)lParam; // Append file version to dialog if (!imp->fileVersion.isNull()) { char buffer[256]; GetWindowText(hWnd, buffer, _countof(buffer)); _tcscat(buffer, TEXT(" ")); _tcscat(buffer, imp->fileVersion); SetWindowText(hWnd, buffer); } CenterWindow(hWnd,GetParent(hWnd)); CheckDlgButton(hWnd, IDC_CHK_HIDDEN, Exporter::mExportHidden); CheckDlgButton(hWnd, IDC_CHK_LIGHTS, Exporter::mExportLights); CheckDlgButton(hWnd, IDC_CHK_CAMERA, Exporter::mExportCameras); CheckDlgButton(hWnd, IDC_CHK_TRANSFORMS, Exporter::mExportTransforms); SetDlgItemText(hWnd, IDC_ED_PRIORITY, FormatText("%.1f", Exporter::mDefaultPriority)); string selection = Exporter::mGameName; string version = Exporter::mNifVersion; string userVer = FormatString("%d", Exporter::mNifUserVersion); for (AppSettingsMap::iterator itr = TheAppSettings.begin(), end = TheAppSettings.end(); itr != end; ++itr) SendDlgItemMessage(hWnd, IDC_CB_GAME, CB_ADDSTRING, 0, LPARAM(itr->Name.c_str())); SendDlgItemMessage(hWnd, IDC_CB_GAME, CB_SELECTSTRING, WPARAM(-1), LPARAM(selection.c_str())); SendDlgItemMessage(hWnd, IDC_CB_VERSION, WM_SETTEXT, 0, LPARAM(version.c_str())); SendDlgItemMessage(hWnd, IDC_CB_USER_VERSION, WM_SETTEXT, 0, LPARAM(userVer.c_str())); imp->mDlgResult = IDCANCEL; } return TRUE; case WM_CLOSE: EndDialog(hWnd, imp->mDlgResult); return TRUE; case WM_COMMAND: if (HIWORD(wParam) == BN_CLICKED) { char tmp[MAX_PATH], *end; bool close = false; switch (LOWORD(wParam)) { case IDOK: // Validity Check GetDlgItemText(hWnd, IDC_CB_VERSION, tmp, MAX_PATH); if (tmp[0] != 0) { int nifVersion = GetVersion(tmp); if (!IsVersionSupported(nifVersion)) { MessageBox(hWnd, FormatString("Version '%s' is not a supported version.", tmp).c_str(), "NifExport", MB_OK|MB_ICONSTOP); return FALSE; } } Exporter::mExportHidden = IsDlgButtonChecked(hWnd, IDC_CHK_HIDDEN); Exporter::mExportLights = IsDlgButtonChecked(hWnd, IDC_CHK_LIGHTS); Exporter::mExportCameras = IsDlgButtonChecked(hWnd, IDC_CHK_CAMERA); Exporter::mExportTransforms = IsDlgButtonChecked(hWnd, IDC_CHK_TRANSFORMS); GetDlgItemText(hWnd, IDC_ED_PRIORITY, tmp, MAX_PATH); Exporter::mDefaultPriority = atof(tmp); GetDlgItemText(hWnd, IDC_CB_GAME, tmp, MAX_PATH); if (AppSettings *appSettings = FindAppSetting(tmp)) { Exporter::mGameName = appSettings->Name; GetDlgItemText(hWnd, IDC_CB_VERSION, tmp, MAX_PATH); Exporter::mNifVersion = tmp; GetDlgItemText(hWnd, IDC_CB_USER_VERSION, tmp, MAX_PATH); Exporter::mNifUserVersion = strtol(tmp, &end, 0); } EndDialog(hWnd, imp->mDlgResult=IDOK); close = true; break; case IDCANCEL: EndDialog(hWnd, imp->mDlgResult=IDCANCEL); close = true; break; } if (close) SendMessage(hWnd, WM_CLOSE, 0, 0); } else if (HIWORD(wParam) == STN_CLICKED) { if (LOWORD(wParam) == IDC_LBL_LINK) { ShellExecute(hWnd, "open", "http://www.niftools.org", NULL, NULL, SW_SHOWDEFAULT); } } else if (HIWORD(wParam) == CBN_SELCHANGE) { if (LOWORD(wParam) == IDC_CB_GAME) { char tmp[MAX_PATH]; GetDlgItemText(hWnd, IDC_CB_GAME, tmp, MAX_PATH); if (AppSettings *appSettings = FindAppSetting(tmp)) { string version = appSettings->NiVersion; string userVer = FormatString("%d", appSettings->NiUserVersion); SendDlgItemMessage(hWnd, IDC_CB_VERSION, WM_SETTEXT, 0, LPARAM(version.c_str())); SendDlgItemMessage(hWnd, IDC_CB_USER_VERSION, WM_SETTEXT, 0, LPARAM(userVer.c_str())); } } } break; } return FALSE; } //--- KfExport ------------------------------------------------------- KfExport::KfExport() { Interface *gi = GetCOREInterface(); TCHAR iniName[MAX_PATH]; if (gi) { LPCTSTR pluginDir = gi->GetDir(APP_PLUGCFG_DIR); PathCombine(iniName, pluginDir, "MaxNifTools.ini"); } else { GetModuleFileName(NULL, iniName, _countof(iniName)); if (LPTSTR fname = PathFindFileName(iniName)) fname = NULL; PathAddBackslash(iniName); PathAppend(iniName, "plugcfg"); PathAppend(iniName, "MaxNifTools.ini"); } iniFileName = iniName; shortDescription = GetIniValue<TSTR>("System", "ShortDescription", "Netimmerse/Gamebryo", iniFileName); fileVersion = GetFileVersion(NULL); } KfExport::~KfExport() { } int KfExport::ExtCount() { return 1; } const TCHAR *KfExport::Ext(int n) { return _T("kf"); } const TCHAR *KfExport::LongDesc() { return _T("Gamebryo File"); } const TCHAR *KfExport::ShortDesc() { return shortDescription; } const TCHAR *KfExport::AuthorName() { return _T("Theo / The Niftools Team"); } const TCHAR *KfExport::CopyrightMessage() { return _T("http://www.niftools.org"); } const TCHAR *KfExport::OtherMessage1() { return _T("http://www.niftools.org"); } const TCHAR *KfExport::OtherMessage2() { return _T("http://www.niftools.org"); } unsigned int KfExport::Version() { return Exporter::mVersion; } void KfExport::ShowAbout(HWND hWnd) { } BOOL KfExport::SupportsOptions(int ext, DWORD options) { return TRUE; } int KfExport::DoExport(const TCHAR *name, ExpInterface *ei, Interface *i, BOOL suppressPrompts, DWORD options) { try { // read application settings AppSettings::Initialize(i); TCHAR iniName[MAX_PATH]; LPCTSTR pluginDir = i->GetDir(APP_PLUGCFG_DIR); PathCombine(iniName, pluginDir, "MaxNifTools.ini"); bool iniNameIsValid = (-1 != _taccess(iniName, 0)); // read config from registry Exporter::readKfConfig(i); AppSettings *appSettings = NULL; if (iniNameIsValid) { string fname = name; // Locate which application to use. If Auto, find first app where this file appears in the root path list string curapp = GetIniValue<string>(KfExportSection, "CurrentApp", "AUTO", iniName); if (0 == _tcsicmp(curapp.c_str(), "AUTO")) { // Scan Root paths for (AppSettingsMap::iterator itr = TheAppSettings.begin(), end = TheAppSettings.end(); itr != end; ++itr){ if ((*itr).IsFileInRootPaths(fname)) { appSettings = &(*itr); break; } } } else { appSettings = FindAppSetting(curapp); } } if (appSettings == NULL && !TheAppSettings.empty()) appSettings = &TheAppSettings.front(); Exporter::mGameName = appSettings->Name; Exporter::mNifVersion = appSettings->NiVersion; Exporter::mNifUserVersion = appSettings->NiUserVersion; if(!suppressPrompts) { if (DialogBoxParam(hInstance, MAKEINTRESOURCE(IDD_KF_PANEL), GetActiveWindow(), KfExportOptionsDlgProc, (LPARAM)this) != IDOK) return true; // write config to registry Exporter::writeKfConfig(i); // write config to root node Exporter::writeConfig(i->GetRootNode()); // Update the current app version appSettings = FindAppSetting(Exporter::mGameName); if (appSettings == NULL && !TheAppSettings.empty()) appSettings = &TheAppSettings.front(); appSettings->NiVersion = Exporter::mNifVersion; appSettings->NiUserVersion = Exporter::mNifUserVersion; appSettings->WriteSettings(i); } int nifVersion = VER_20_0_0_5; int nifUserVer = Exporter::mNifUserVersion; if (!Exporter::mNifVersion.empty()) { nifVersion = GetVersion(Exporter::mNifVersion); if (!IsVersionSupported(nifVersion)) throw exception(FormatString("Version '%s' is not a supported version.").c_str()); } Exporter::mSelectedOnly = (options&SCENE_EXPORT_SELECTED) != 0; Exporter exp(i, appSettings); Ref<NiControllerSequence> root = new NiControllerSequence(); TCHAR fname[MAX_PATH]; _tcscpy(fname, PathFindFileName(name)); PathRemoveExtension(fname); root->SetName(fname); Exporter::Result result = exp.doAnimExport(root); if (result!=Exporter::Ok) throw exception("Unknown error."); Niflib::NifInfo info(nifVersion, nifUserVer, nifUserVer); info.creator = Exporter::mCreatorName; info.exportInfo1 = "Niflib"; info.exportInfo2 = FormatText("Niftools Max Plugins %s", fileVersion.data()); WriteNifTree(name, StaticCast<NiObject>(root), info); } catch (exception &e) { MessageBox(NULL, e.what(), "Export Error", MB_OK); return true; } catch (...) { MessageBox(NULL, "Unknown error.", "Export Error", MB_OK); return true; } return TRUE; }