diff --git a/pencil++2.sln b/pencil++2.sln new file mode 100644 index 0000000..6b9cadc --- /dev/null +++ b/pencil++2.sln @@ -0,0 +1,20 @@ + +Microsoft Visual Studio Solution File, Format Version 11.00 +# Visual Studio 2010 +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "pencil++2", "pencil++2\pencil++2.vcxproj", "{09590B42-9C0E-4C79-B545-80A2F20F8D61}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Win32 = Debug|Win32 + Release|Win32 = Release|Win32 + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {09590B42-9C0E-4C79-B545-80A2F20F8D61}.Debug|Win32.ActiveCfg = Debug|Win32 + {09590B42-9C0E-4C79-B545-80A2F20F8D61}.Debug|Win32.Build.0 = Debug|Win32 + {09590B42-9C0E-4C79-B545-80A2F20F8D61}.Release|Win32.ActiveCfg = Release|Win32 + {09590B42-9C0E-4C79-B545-80A2F20F8D61}.Release|Win32.Build.0 = Release|Win32 + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection +EndGlobal diff --git a/pencil++2/3dmmclass.h b/pencil++2/3dmmclass.h new file mode 100644 index 0000000..e69de29 diff --git a/pencil++2/DecompProxy.dll b/pencil++2/DecompProxy.dll new file mode 100644 index 0000000..9d4305b Binary files /dev/null and b/pencil++2/DecompProxy.dll differ diff --git a/pencil++2/DecompProxy.lib b/pencil++2/DecompProxy.lib new file mode 100644 index 0000000..851de11 Binary files /dev/null and b/pencil++2/DecompProxy.lib differ diff --git a/pencil++2/applychanges.cpp b/pencil++2/applychanges.cpp new file mode 100644 index 0000000..0c11c7b --- /dev/null +++ b/pencil++2/applychanges.cpp @@ -0,0 +1,151 @@ +/* 3DMM Pencil++ 2 + Copyright (C) 2005 Frankie Weindel */ +#include "pencil.h" + +bool changesMade = false; + + + + +int PromptChangesMade() +{ + if (changesMade) + { + int ret = MessageBox(maindlg::hWnd,L"Changes have been made to this quad. Save Changes?", L"Changes Made", MB_YESNOCANCEL | MB_ICONQUESTION); + switch (ret) + { + case IDYES: + return CHANGE_YES; + break; + case IDNO: + return CHANGE_NO; + break; + case IDCANCEL: + return CHANGE_CANCEL; + break; + } + } + else return CHANGE_YES; +} + +void ChangeMade() +{ + EnableWindow(maindlg::hWndApplyBtn, true); + changesMade = true; +} + +void ResetChangeMade() +{ + EnableWindow(maindlg::hWndApplyBtn, false); + changesMade = false; +} + +std::wstring GenQuadReferenceItemString(FF_3dmmIndexReference ref, SQuad *quad) +{ + std::wstringstream ss; + if (!dmmfile.getQuad(ref.type, ref.id, quad)) + { + ss << ConvertQuadToString(ref.type) << L" - " << ref.id << L" : " << ref.refid << L" [QUAD NOT FOUND]"; + } + else + { + if (quad->string.getStringType() > STR_NONE) + { + ss << ConvertQuadToString(ref.type) << L" - " << ref.id << L" : " << ref.refid << L" \"" << quad->string.getString() << L"\""; + } + else + { + ss << ConvertQuadToString(ref.type) << L" - " << ref.id << L" : " << ref.refid; + } + } + return ss.str(); +} + +void ChangeReference() +{ + unsigned long cursel = (unsigned long)SendMessage(refchild::hWndRefList, LB_GETCURSEL, 0,0); + if (cursel == LB_ERR) return; + wchar_t buffer[5]; + SendMessage(refchild::hWndQuadTxt, WM_GETTEXT, (WPARAM)4+1, (LPARAM)buffer); + //Check for bad QUAD + if (_GetStringType(buffer) == STR_UNICODE) + { + MessageBox(refchild::hWnd, QUAD_UNICODE_USED, L"Error", MB_OK | MB_ICONERROR); + return; + } + if (wcslen(buffer) != 4) + { + MessageBox(refchild::hWnd,QUAD_FOUR_CHARACTERS, L"Error", MB_OK | MB_ICONERROR); + return; + } + /////////////////////////// + FF_3dmmIndexReference newref; + newref.type = ConvertStringToQuad(buffer); + newref.id = GetValueFromHWND(refchild::hWndIDTxt); + newref.refid = GetValueFromHWND(refchild::hWndRefIDTxt); + + if (curquad.quadid.type == newref.type && curquad.quadid.id == newref.id) + { + MessageBox(refchild::hWnd,QUAD_REFERENCED_ITSELF, L"Error", MB_OK | MB_ICONERROR); + return; + } + FF_3dmmIndexReference oldref; + curquad.references.getReference((unsigned short)cursel, &oldref); + if (!curquad.references.checkReference(newref, oldref)) + { + MessageBox(refchild::hWnd, QUAD_REFID_EXISTS, L"Error", MB_OK | MB_ICONERROR); + return; + } + SendMessage(refchild::hWndRefList, LB_DELETESTRING, (WPARAM)cursel, 0); + curquad.references.removeReference((unsigned short)cursel); + unsigned short insertnum; + insertnum = curquad.references.addReference(newref); + SQuad quad; + unsigned long listnum = (unsigned long)SendMessage(refchild::hWndRefList, LB_INSERTSTRING, (WPARAM)insertnum, (LPARAM)GenQuadReferenceItemString(newref,&quad).c_str()); + SendMessage(refchild::hWndRefList, LB_SETITEMDATA, (WPARAM)listnum,(LPARAM)quad.uniqueid); + SendMessage(refchild::hWndRefList, LB_SETCURSEL, (WPARAM)listnum, 0); + +} + +void ApplyChanges() +{ + unsigned long cursel = (unsigned long)SendMessage(maindlg::hWndQuadList, LB_GETCURSEL, 0, 0); + if (cursel == LB_ERR) return; + wchar_t buffer[5]; + SendMessage(maindlg::hWndQuadTxt, WM_GETTEXT, (WPARAM)4+1, (LPARAM)buffer); + //Check for bad QUAD + if (_GetStringType(buffer) == STR_UNICODE) + { + MessageBox(maindlg::hWnd, QUAD_UNICODE_USED, L"Error", MB_OK | MB_ICONEXCLAMATION); + return; + } + if (wcslen(buffer) != 4) + { + MessageBox(maindlg::hWnd,QUAD_FOUR_CHARACTERS, L"Error", MB_OK | MB_ICONEXCLAMATION); + return; + } + /////////////////////////// + curquad.quadid.type = ConvertStringToQuad(buffer); + curquad.quadid.id = GetValueFromHWND(maindlg::hWndIDTxt); + unsigned short strlen = (unsigned short)SendMessage(maindlg::hWndStrTxt, WM_GETTEXTLENGTH, 0, 0); + wchar_t *stringbuffer = new wchar_t[strlen + 1]; + SendMessage(maindlg::hWndStrTxt, WM_GETTEXT, (WPARAM)strlen + 1, (LPARAM)stringbuffer); + stringbuffer[strlen] = 0; + curquad.string.setString(stringbuffer); + delete [] stringbuffer; + if (!dmmfile.changeQuad(&curquad)) + { + MessageBox(maindlg::hWnd, QUAD_QUADID_EXISTS, L"Error", MB_OK | MB_ICONEXCLAMATION ); + return; + } + curSecDataIsNew = false; + std::wstringstream ss; + if (curquad.string.getStringType() > STR_NONE) ss << ConvertQuadToString(curquad.quadid.type) << L" - " << curquad.quadid.id << L" \"" << curquad.string.getString() << L"\""; + else ss << ConvertQuadToString(curquad.quadid.type) << L" - " << curquad.quadid.id; + SendMessage(maindlg::hWndQuadList, LB_DELETESTRING, (WPARAM)cursel,0); + unsigned long listnum = (unsigned long)SendMessage(maindlg::hWndQuadList, LB_INSERTSTRING, (WPARAM)cursel,(LPARAM) ss.str().c_str()); + SendMessage(maindlg::hWndQuadList, LB_SETITEMDATA, (WPARAM)listnum,(LPARAM)curquad.uniqueid); + SendMessage(maindlg::hWndQuadList, LB_SETCURSEL, (WPARAM)cursel,0); + ResetChangeMade(); + +} \ No newline at end of file diff --git a/pencil++2/cpencilfuncs.cpp b/pencil++2/cpencilfuncs.cpp new file mode 100644 index 0000000..7af9394 --- /dev/null +++ b/pencil++2/cpencilfuncs.cpp @@ -0,0 +1,336 @@ +/* 3DMM Pencil++ 2 + Copyright (C) 2005 Frankie Weindel */ + +#include "pencilclass.h" + +CPencil::CPencil() +{ + fileIsOpen = false; + lastuniqueid = 0; + directorysort.setSortType(GETQUAD_DIRSORT); +} +CPencil::~CPencil() +{ + close(); +} + +unsigned long CPencil::getQuadNum(unsigned long uniqueid, int quadsort) +{ + for (unsigned long quadnum = 0; quadnum < quads.size(); quadnum++) + { + switch (quadsort) + { + case GETQUAD_DIRSORT: + if (quads[quadnum]->uniqueid == uniqueid) return quadnum; + break; + case GETQUAD_QUADORDERSORT: + if (quadindexsort.getQuadPT(quadnum)->uniqueid == uniqueid) + { + return quadnum; + } + break; + } + } + return 0xFFFFFFFF; +} + +bool CPencil::getQuad(unsigned long uniqueid, SQuad *retQuad) +{ + for (std::vector::iterator itr = quads.begin(); itr != quads.end(); itr++) //Find Quad + { + if ((*itr)->uniqueid == uniqueid) + { + retQuad->mode = (*itr)->mode; + retQuad->quadid = (*itr)->quadid; + retQuad->references = (*itr)->references; + retQuad->section = (*itr)->section; + retQuad->string = (*itr)->string; + retQuad->temp = (*itr)->temp; + retQuad->uniqueid = (*itr)->uniqueid; + return true; + } + } + return false; +} + +SQuad CPencil::getQuad(unsigned long quadnum, int quadsort) +{ + unsigned long numquads = (unsigned long)quads.size(); + if (quadnum < quads.size()) + { + switch (quadsort) + { + case GETQUAD_DIRSORT: + return (*(quads[quadnum])); + break; + case GETQUAD_QUADORDERSORT: + return (*(quadindexsort.getQuadPT(quadnum))); + break; + default: + return (*(quads[quadnum])); + break; + } + } + else + { + SQuad error; + error.quadid.id = -1; + error.mode = -1; + error.quadid.type = 0xFFFFFFFF; + raiseError(PERROR_INVALIDQUADNUM); + return error; + } + +}; + +bool CPencil::getQuad(SQuadID quadid, SQuad *retQuad) +{ + return getQuad(quadid.type, quadid.id, retQuad); +} + +bool CPencil::getQuad(quad type, unsigned long id, SQuad *retQuad) +{ + for (std::vector::iterator itr = quads.begin(); itr != quads.end(); itr++) //Find Quad + { + if ((*itr)->quadid.type == type && (*itr)->quadid.id == id) + { + if (retQuad != NULL) + { + retQuad->mode = (*itr)->mode; + retQuad->quadid = (*itr)->quadid; + retQuad->references = (*itr)->references; + retQuad->section = (*itr)->section; + retQuad->string = (*itr)->string; + retQuad->temp = (*itr)->temp; + retQuad->uniqueid = (*itr)->uniqueid; + } + return true; + } + } +return false; +} + +bool CPencil::getQuadRefBy(SQuadID quadid, std::vector *retRefBy) +{ + return getQuadRefBy(quadid.type, quadid.id, retRefBy); +} + +bool CPencil::getQuadRefBy(quad type, unsigned long id, std::vector *retRefBy) +{ + for (std::vector::iterator itr = quads.begin(); itr != quads.end(); itr++) //Find Quad + { + unsigned short numrefs = (*itr)->references.getNumReferences(); + for (unsigned short refnum = 0; refnum < numrefs; refnum++) + { + FF_3dmmIndexReference reference; + if ((*itr)->references.getReference(refnum,&reference)) + { + if (reference.type == type && reference.id == id) + { + SRefBy refby; + refby.quadid = (*itr)->quadid; + refby.refid = reference.refid; + refby.string = (*itr)->string; + refby.uniqueid = (*itr)->uniqueid; + retRefBy->push_back(refby); + } + } + } + } + return true; +} + +int _GetStringType(const wchar_t *wstr) +{ + size_t strlen = wcslen(wstr); + if (strlen == 0) + { + return STR_NONE; + } + for (unsigned int curchar = 0; curchar < strlen; curchar++) + { + if (HIBYTE(wstr[curchar]) != 0) + { + return STR_UNICODE; + } + } + return STR_ASCII; + +} + +void ReverseQuadStr(char sQuad[5]) +{ + char sQuad2[4]; + sQuad2[0] = sQuad[3]; + sQuad2[1] = sQuad[2]; + sQuad2[2] = sQuad[1]; + sQuad2[3] = sQuad[0]; + + sQuad[0] = sQuad2[0]; + sQuad[1] = sQuad2[1]; + sQuad[2] = sQuad2[2]; + sQuad[3] = sQuad2[3]; +} + +int ConvertStrToWStr(const char *str, wchar_t *wstr) +{ + int stringlen = (int)strlen(str); + for (int strpos = 0; strpos < stringlen;strpos++) + { + wstr[strpos] = str[strpos]; + } + wstr[stringlen] = 0; + return 1; +} + +int ConvertWStrToStr(const wchar_t *wstr, char *str) +{ + int stringlen = (int)wcslen(wstr); + for (int strpos = 0; strpos < stringlen;strpos++) + { + memcpy(&str[strpos],&wstr[strpos],1); + } + str[stringlen] = 0; + return 1; +} + +int ConvertQuadToString(quad qQuad, char sQuad[5]) +{ + memcpy(sQuad,&qQuad,4); + ReverseQuadStr(sQuad); + sQuad[4] = 0; + + return 1; +} + +int ConvertQuadToString(quad qQuad, wchar_t sQuad[5]) +{ + char sQuad2[5]; + memcpy(sQuad2,&qQuad,4); + ReverseQuadStr(sQuad2); + sQuad2[4] = 0; + + ConvertStrToWStr(sQuad2,sQuad); + sQuad[4] = 0; + return 1; +} + +std::wstring ConvertQuadToString(quad qQuad) +{ + char sQuad2[5]; + wchar_t sQuad[5]; + memcpy(sQuad2,&qQuad,4); + ReverseQuadStr(sQuad2); + sQuad2[4] = 0; + + ConvertStrToWStr(sQuad2,sQuad); + sQuad[4] = 0; + return (std::wstring(sQuad)); +} + +quad ConvertStringToQuad(const wchar_t sQuad[5]) +{ + quad ret; + BYTE sQuad2[4]; + sQuad2[3] = (char)sQuad[0]; + sQuad2[2] = (char)sQuad[1]; + sQuad2[1] = (char)sQuad[2]; + sQuad2[0] = (char)sQuad[3]; + memcpy(&ret,sQuad2,4); + return ret; +} + +quad ConvertStringToQuad(const char sQuad[5]) +{ + quad ret; + char sQuad2[4]; + sQuad2[3] = sQuad[0]; + sQuad2[2] = sQuad[1]; + sQuad2[1] = sQuad[2]; + sQuad2[0] = sQuad[3]; + memcpy(&ret,sQuad2,4); + //wchar_t buff[5]; + //ConvertQuadToString(ret,buff); + //MessageBox(NULL,buff,buff,MB_OK); + return ret; +} + +int CompareQuads(const char *sQuad1, const char *sQuad2) +{ + if (strlen(sQuad1) != 4 || strlen(sQuad2) != 4) + { + return -1; + } + if (sQuad1[0] == sQuad2[0] && sQuad1[1] == sQuad2[1] && sQuad1[2] == sQuad2[2] && sQuad1[3] == sQuad2[3]) + { + return 1; + } + else + { + return 0; + } +} + +int CompareQuads(quad qQuad1, const char *sQuad2) +{ + + if (strlen(sQuad2) != 4 ) + { + return -1; + } + + char rQuad2[4]; + rQuad2[0] = sQuad2[3]; + rQuad2[1] = sQuad2[2]; + rQuad2[2] = sQuad2[1]; + rQuad2[3] = sQuad2[0]; + + quad qQuad2; + CopyMemory(&qQuad2,rQuad2,4); + return qQuad1 == qQuad2; +} + +size_t FileSize(FILE *fp) +{ + unsigned long curspot = ftell(fp); + fseek(fp,0,SEEK_END); + size_t filesize = ftell(fp); + fseek(fp,curspot,SEEK_SET); + return filesize; +} + +int fgoto(FILE *fp, long offset) +{ + return fseek(fp,-(ftell(fp) - offset),SEEK_CUR); +} + +unsigned long fsize(FILE *fp) +{ + unsigned long curoffset = ftell(fp); + fseek(fp,0,SEEK_END); + unsigned long filesize = ftell(fp); + fseek(fp,curoffset, SEEK_SET); + return filesize; +} + +quad GetQuadFromHWND(HWND hWnd) +{ + unsigned short textlen = (unsigned short)SendMessage(hWnd, WM_GETTEXTLENGTH, 0,0); + wchar_t buffer[5]; + SendMessage(hWnd, WM_GETTEXT, (WPARAM)4+1, (LPARAM)buffer); + return ConvertStringToQuad(buffer); +} + +int fixstring(char *string) +{ + int size = strlen(string) + 1; + for (int num = 0; num < size; num++) + { + if (string[num] == -110) + { + string[num] = 0x27; + } + + } + return 1; +} \ No newline at end of file diff --git a/pencil++2/decompproxy.h b/pencil++2/decompproxy.h new file mode 100644 index 0000000..16b7946 --- /dev/null +++ b/pencil++2/decompproxy.h @@ -0,0 +1,10 @@ +#ifdef DECOMPPROXY_EXPORTS +#define DECOMPPROXY_API __declspec(dllexport) +#else +#define DECOMPPROXY_API __declspec(dllimport) +#endif + +DECOMPPROXY_API int Init(const char *filename); +DECOMPPROXY_API int Shutdown(); +DECOMPPROXY_API int GetSize(unsigned char* section, int sectionsize); +DECOMPPROXY_API int DecompressSmart(unsigned char* section, int sectionsize, unsigned char* outbuffer); \ No newline at end of file diff --git a/pencil++2/dialogcontrols.h b/pencil++2/dialogcontrols.h new file mode 100644 index 0000000..a4e8b1f --- /dev/null +++ b/pencil++2/dialogcontrols.h @@ -0,0 +1,79 @@ +/* 3DMM Pencil++ 2 + Copyright (C) 2005 Frankie Weindel */ + +#include + +////////////////////////////////// +// Main Dialog (maindialog.cpp) // +////////////////////////////////// + + +namespace maindlg +{ + extern HWND hWnd; + extern HWND hWndQuadList; + extern HWND hWndQuadTreeView; + extern HWND hWndMoveUpBtn; + extern HWND hWndMoveDownBtn; + extern HWND hWndAddQuadBtn; + extern HWND hWndRemoveQuadBtn; + extern HWND hWndQuadLbl; + extern HWND hWndIDLbl; + extern HWND hWndStrLbl; + extern HWND hWndQuadTxt; + extern HWND hWndIDTxt; + extern HWND hWndStrTxt; + extern HWND hWndTab; + extern HWND hWndSectDataBox; + extern HWND hWndOffLenLbl; + extern HWND hWndImportBtn; + extern HWND hWndExportBtn; + extern HWND hWndApplyBtn; + extern HMENU hMenu; +}; +namespace refchild +{ + extern HWND hWnd; + extern HWND hWndRefBox; + extern HWND hWndRefList; + extern HWND hWndQuadLbl; + extern HWND hWndIDLbl; + extern HWND hWndRefIDLbl; + extern HWND hWndQuadTxt; + extern HWND hWndIDTxt; + extern HWND hWndRefIDTxt; + extern HWND hWndAddBtn; + extern HWND hWndRemoveBtn; + extern HWND hWndChangeBtn; + extern HWND hWndQSelOKBtn; + extern HWND hWndRefByBox; + extern HWND hWndRefByList; +}; +namespace viewhexchild +{ + extern HWND hWnd; + extern HWND hWndHexTxt; +}; + +namespace editheader +{ + extern HWND hWnd; + extern HWND hWndSignature; + extern HWND hWndUnk1; + extern HWND hWndUnk2; + extern HWND hWndStringType; +}; + +namespace finddlg +{ + extern HWND hWnd; + extern HWND hWndQuadTxt; + extern HWND hWndIDTxt; + extern HWND hWndStrTxt; + extern HWND hWndQuadIDOpt; + extern HWND hWndStrOpt; + extern HWND hWndUpOpt; + extern HWND hWndDownOpt; + extern HWND hWndFindBtn; + extern HWND hWndCancelBtn; +}; \ No newline at end of file diff --git a/pencil++2/editstructs.h b/pencil++2/editstructs.h new file mode 100644 index 0000000..e69de29 diff --git a/pencil++2/errorhandler.cpp b/pencil++2/errorhandler.cpp new file mode 100644 index 0000000..71a7551 --- /dev/null +++ b/pencil++2/errorhandler.cpp @@ -0,0 +1,43 @@ +/* 3DMM Pencil++ 2 + Copyright (C) 2005 Frankie Weindel */ + +#include "pencilclass.h" + +void CPencil::raiseError(int errnum) +{ + lasterror = errnum; +} + +std::wstring CPencil::getLastErrorText() +{ + return getErrorText(lasterror); +} +std::wstring CPencil::getErrorText(int errnum) +{ + std::wstring errstr; + switch (errnum) + { + case PERROR_NONE: + errstr = PERRORTXT_NONE; + break; + case PERROR_FOPEN: + errstr = PERRORTXT_FOPEN; + break; + case PERROR_NOTVALID: + errstr = PERRORTXT_NOTVALID; + break; + case PERROR_INVALIDQUADNUM: + errstr = PERROR_INVALIDQUADNUM; + break; + case PERROR_FOPENSAVE: + errstr = PERRORTXT_FOPENSAVE; + break; + case PERROR_ALREADYOPENED: + errstr = PERRORTXT_ALREADYOPENED; + break; + case PERROR_NOFPATHEXISTS: + errstr = PERRORTXT_NOFPATHEXISTS; + break; + } + return errstr; +} \ No newline at end of file diff --git a/pencil++2/externalmessaging.cpp b/pencil++2/externalmessaging.cpp new file mode 100644 index 0000000..346d5b5 --- /dev/null +++ b/pencil++2/externalmessaging.cpp @@ -0,0 +1,49 @@ +#include "externalmessaging.h" + +LRESULT SendPencilMessage(UINT message, LPARAM lParam, WPARAM wParam) +{ + switch (message) + { + case MSG_GETCURQUADID: + { + SExtQuadID *quadid = (SExtQuadID*)lParam; + quadid->type = curquad.quadid.type; + quadid->id = curquad.quadid.id; + return 0; + } + case MSG_GETCURQUADSTRING: + { + unsigned int sizeofbuffer = (unsigned int)wParam; + wchar_t *buffer = (wchar_t*)lParam; + unsigned short strsize = curquad.string.getString().size(); + if (sizeofbuffer - 1 < strsize) + { + wmemcpy(buffer, curquad.string.getString().c_str(), sizeofbuffer - 1); + buffer[sizeofbuffer] = 0; + return 1; + } + wmemcpy(buffer, curquad.string.getString().c_str(), strsize + 1); + return 0; + } + case MSG_GETCURQUADSTRINGLEN: + { + return curquad.string.getString().size(); + } + case MSG_ALLOCATEBYTEARRAY: + { + //BYTE *data = (BYTE*)GlobalAlloc(GMEM_FIXED,(unsigned int) lParam); + + BYTE *data = new BYTE[(unsigned int) lParam]; + return (LRESULT)data; + } + case MSG_SAVECURQUADSECTION: + { + BYTE* data = (BYTE*)wParam; + SetCurSection(data, (unsigned int) lParam); + DisplaySectionInfo(); + ChangeMade(); + return 0; + } + } + return 0; +} \ No newline at end of file diff --git a/pencil++2/externalmessaging.h b/pencil++2/externalmessaging.h new file mode 100644 index 0000000..f369f15 --- /dev/null +++ b/pencil++2/externalmessaging.h @@ -0,0 +1,9 @@ +#ifndef _EXTERNALMESSAGING_H +#define _EXTERNALMESSAGING_H + +#include "pencil.h" +#include "extmessages.h" + +extern LRESULT SendPencilMessage(UINT message, LPARAM lParam, WPARAM wParam); + +#endif \ No newline at end of file diff --git a/pencil++2/extmessages.h b/pencil++2/extmessages.h new file mode 100644 index 0000000..aa6cf0b --- /dev/null +++ b/pencil++2/extmessages.h @@ -0,0 +1,36 @@ +///////////////////////////////////// +// 3DMM Pencil++ 2 Messages Header // +///////////////////////////////////// + +typedef unsigned long quad; +typedef unsigned char BYTE; +struct SExtQuadID +{ + quad type; + unsigned long id; +}; +//struct SExtString +//{ +// wchar_t *string; +// int stringtype; +// unsigned short stringlen; +//} +//struct SExtSection +//{ +// BYTE *data; +// size_t datalen; +// bool compressed; +// +//} +// +//struct SExtQuad +//{ +// SExtQuadID quadid; +// SExtString string; +//} + +#define MSG_GETCURQUADID 0 +#define MSG_GETCURQUADSTRING 1 +#define MSG_GETCURQUADSTRINGLEN 2 +#define MSG_ALLOCATEBYTEARRAY 3 +#define MSG_SAVECURQUADSECTION 4 \ No newline at end of file diff --git a/pencil++2/fileformatstructs.h b/pencil++2/fileformatstructs.h new file mode 100644 index 0000000..fd324f4 --- /dev/null +++ b/pencil++2/fileformatstructs.h @@ -0,0 +1,57 @@ +/* 3DMM Pencil++ 2 + Copyright (C) 2005 Frankie Weindel */ + +#ifndef _FILEFORMATSTRUCTS_H +#define _FILEFORMATSTRUCTS_H + +typedef unsigned long quad; +typedef unsigned char BYTE; + +struct FF_3dmmHeader +{ + quad identifier; + quad signature; + short unk1; + short unk2; + unsigned long magicnum; + unsigned long filelen; + unsigned long indexoffset; + unsigned long indexlen; + unsigned long filelen2; + BYTE zeros[96]; +}; + + + +struct FF_3dmmIndexHeader +{ + unsigned long magicnum; + unsigned long numsections; + unsigned long quadindexlen; + unsigned long FFFFFFFF; + unsigned long unk20; //Always 20 +}; + +struct FF_3dmmIndexQuad +{ + quad type; + unsigned long id; + unsigned long secoffset; + BYTE mode; + BYTE seclength[3]; + unsigned short numreferences; + unsigned short timesreferenced; +}; +struct FF_3dmmIndexReference +{ + quad type; + unsigned long id; + long refid; +}; +struct FF_3dmmDirectoryEntry +{ + long offset; + size_t length; +}; + +#endif \ No newline at end of file diff --git a/pencil++2/find.cpp b/pencil++2/find.cpp new file mode 100644 index 0000000..19860d4 --- /dev/null +++ b/pencil++2/find.cpp @@ -0,0 +1,163 @@ +#include "pencilclass.h" + +int wildcmp(wchar_t *wild,wchar_t *string) +{ + wchar_t *cp, *mp; + + while ((*string) && (*wild != L'*')) { + if ((*wild != *string) && (*wild != L'?')) { + return 0; + } + wild++; + string++; + } + + while (*string) { + if (*wild == L'*') { + if (!*++wild) { + return 1; + } + mp = wild; + cp = string+1; + } else if ((*wild == *string) || (*wild == L'?')) { + wild++; + string++; + } else { + wild = mp; + string = cp++; + } + } + + while (*wild == L'*') { + wild++; + } + return !*wild; +} + +bool CPencil::checkQuadNumValidity(unsigned long quadnum) +{ + if (quadnum >= quads.size()) return false; + return true; +} + +std::vector* CPencil::getQuadPointerVector(int quadsort) +{ + switch (quadsort) + { + case GETQUAD_SECTIONORDERSORT: + return &quads; + break; + case GETQUAD_QUADORDERSORT: + return &quadindexsort.quadpointers; + break; + case GETQUAD_DIRSORT: + return &directorysort.quadpointers; + break; + } + return &quads; +} + +unsigned long CPencil::findFromQuad_Type(quad type, unsigned long quadnumstart, int direction, int quadsort) +{ + if (!checkQuadNumValidity(quadnumstart)) return FIND_ERR; + FindQuad find; + find.type = type; + std::vector *searchquads = getQuadPointerVector(quadsort); + + + if (direction == FIND_DOWN) + { + std::vector::iterator Iter; + if ((Iter = std::find_if((*searchquads).begin() + quadnumstart + 1,(*searchquads).end(),find)) != (*searchquads).end()) + { + return unsigned long(Iter - (*searchquads).begin()); + } + } + else if (direction == FIND_UP) + { + std::vector::reverse_iterator Iter; + if ((Iter = std::find_if((*searchquads).rbegin() + ((*searchquads).size()-(quadnumstart)),(*searchquads).rend(),find)) != (*searchquads).rend()) + { + return unsigned long(-(Iter - (*searchquads).rend())) - 1; + } + } + return FIND_ERR; +} +unsigned long CPencil::findFromQuad_ID(unsigned long id, unsigned long quadnumstart, int direction, int quadsort) +{ + if (!checkQuadNumValidity(quadnumstart)) return FIND_ERR; + FindID find; + find.id = id; + std::vector *searchquads = getQuadPointerVector(quadsort); + + + if (direction == FIND_DOWN) + { + std::vector::iterator Iter; + if ((Iter = std::find_if((*searchquads).begin() + quadnumstart + 1,(*searchquads).end(),find)) != (*searchquads).end()) + { + return unsigned long(Iter - (*searchquads).begin()); + } + } + else if (direction == FIND_UP) + { + std::vector::reverse_iterator Iter; + if ((Iter = std::find_if((*searchquads).rbegin() + ((*searchquads).size()-(quadnumstart)),(*searchquads).rend(),find)) != (*searchquads).rend()) + { + return unsigned long(-(Iter - (*searchquads).rend())) - 1; + } + } + return FIND_ERR; +} +unsigned long CPencil::findFromQuad_QuadID(SQuadID quadid, unsigned long quadnumstart, int direction, int quadsort) +{ + if (!checkQuadNumValidity(quadnumstart)) return FIND_ERR; + FindQuadID find; + find.quadid = quadid; + std::vector *searchquads = getQuadPointerVector(quadsort); + + + if (direction == FIND_DOWN) + { + std::vector::iterator Iter; + if ((Iter = std::find_if((*searchquads).begin() + quadnumstart + 1,(*searchquads).end(),find)) != (*searchquads).end()) + { + return unsigned long(Iter - (*searchquads).begin()); + } + } + else if (direction == FIND_UP) + { + std::vector::reverse_iterator Iter; + if ((Iter = std::find_if((*searchquads).rbegin() + ((*searchquads).size()-(quadnumstart)),(*searchquads).rend(),find)) != (*searchquads).rend()) + { + return unsigned long(-(Iter - (*searchquads).rend())) - 1; + } + } + return FIND_ERR; +} +unsigned long CPencil::findFromQuad_String(std::wstring str, unsigned long quadnumstart, int direction, int quadsort) +{ +if (!checkQuadNumValidity(quadnumstart)) return FIND_ERR; + FindString find; + find.str = str; + std::vector *searchquads = getQuadPointerVector(quadsort); + + + if (direction == FIND_DOWN) + { + std::vector::iterator Iter; + if ((Iter = std::find_if((*searchquads).begin() + quadnumstart + 1,(*searchquads).end(),find)) != (*searchquads).end()) + { + return unsigned long(Iter - (*searchquads).begin()); + } + } + else if (direction == FIND_UP) + { + std::vector::reverse_iterator Iter; + if ((Iter = std::find_if((*searchquads).rbegin() + ((*searchquads).size()-(quadnumstart)),(*searchquads).rend(),find)) != (*searchquads).rend()) + { + return unsigned long(-(Iter - (*searchquads).rend())) - 1; + } + } + return FIND_ERR; +} \ No newline at end of file diff --git a/pencil++2/find.h b/pencil++2/find.h new file mode 100644 index 0000000..e69de29 diff --git a/pencil++2/finddlg.cpp b/pencil++2/finddlg.cpp new file mode 100644 index 0000000..ef48969 --- /dev/null +++ b/pencil++2/finddlg.cpp @@ -0,0 +1,158 @@ +/* 3DMM Pencil++ 2 + Copyright (C) 2005 Frankie Weindel */ + +#include "pencil.h" + +namespace finddlg +{ + HWND hWnd; + HWND hWndQuadTxt; + HWND hWndIDTxt; + HWND hWndStrTxt; + HWND hWndQuadIDOpt; + HWND hWndStrOpt; + HWND hWndUpOpt; + HWND hWndDownOpt; + HWND hWndFindBtn; + HWND hWndCancelBtn; +}; + +LRESULT CALLBACK FindDlgProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam) +{ + switch(msg) + { + case WM_INITDIALOG: + { + finddlg::hWnd = hWnd; + finddlg::hWndQuadTxt = GetDlgItem(hWnd,IDC_FIND_TYPE); + finddlg::hWndIDTxt = GetDlgItem(hWnd,IDC_FIND_ID); + finddlg::hWndStrTxt = GetDlgItem(hWnd,IDC_FIND_STR); + finddlg::hWndQuadIDOpt = GetDlgItem(hWnd,IDC_SEARCHBY_QUADID); + finddlg::hWndStrOpt = GetDlgItem(hWnd,IDC_SEARCHBY_STRING); + finddlg::hWndUpOpt = GetDlgItem(hWnd,IDC_DIRECT_UP); + finddlg::hWndDownOpt = GetDlgItem(hWnd,IDC_DIRECT_DOWN); + finddlg::hWndFindBtn = GetDlgItem(hWnd,IDC_FINDNEXT); + finddlg::hWndCancelBtn = GetDlgItem(hWnd,IDCANCEL); + + SendMessage(finddlg::hWndQuadTxt, EM_SETLIMITTEXT, (WPARAM)4, (LPARAM)0); + SetWindowLongPtr(hWnd, GWLP_HWNDPARENT,(LONG)(LONG_PTR)maindlg::hWnd); + + SendMessage(finddlg::hWndQuadIDOpt,BM_SETCHECK,(WPARAM)BST_CHECKED,0); + SendMessage(finddlg::hWndDownOpt,BM_SETCHECK,(WPARAM)BST_CHECKED,0); + return 1; + } + break; + case WM_QUIT: + case WM_CLOSE: + finddlg::hWnd = NULL; + finddlg::hWndQuadTxt = NULL; + finddlg::hWndIDTxt = NULL; + finddlg::hWndStrTxt = NULL; + finddlg::hWndQuadIDOpt = NULL; + finddlg::hWndStrOpt = NULL; + finddlg::hWndUpOpt = NULL; + finddlg::hWndDownOpt = NULL; + finddlg::hWndFindBtn = NULL; + finddlg::hWndCancelBtn = NULL; + EndDialog(hWnd,0); + break; + case WM_COMMAND: + switch(LOWORD(wParam)) + { + case IDCANCEL: + SendMessage(hWnd,WM_CLOSE,0,0); + break; + case IDC_FIND_TYPE: + switch(HIWORD(wParam)) + { + case EN_SETFOCUS: + SendMessage(finddlg::hWndQuadIDOpt,BM_SETCHECK,(WPARAM)BST_CHECKED,0); + SendMessage(finddlg::hWndStrOpt,BM_SETCHECK,(WPARAM)BST_UNCHECKED,0); + //MessageBox(hWnd,L"SDFDS",L"SDFDS",MB_OK); + break; + } + break; + case IDC_FIND_ID: + switch(HIWORD(wParam)) + { + case EN_SETFOCUS: + SendMessage(finddlg::hWndQuadIDOpt,BM_SETCHECK,(WPARAM)BST_CHECKED,0); + SendMessage(finddlg::hWndStrOpt,BM_SETCHECK,(WPARAM)BST_UNCHECKED,0); + //MessageBox(hWnd,"SDFDS","SDFDS",MB_OK); + break; + } + break; + case IDC_FIND_STR: + switch(HIWORD(wParam)) + { + case EN_SETFOCUS: + SendMessage(finddlg::hWndStrOpt,BM_SETCHECK,(WPARAM)BST_CHECKED,0); + SendMessage(finddlg::hWndQuadIDOpt,BM_SETCHECK,(WPARAM)BST_UNCHECKED,0); + //MessageBox(hWnd,"SDFDS","SDFDS",MB_OK); + break; + } + break; + case IDC_FINDNEXT: + { + FindNext(); + } + } + break; + + default:; + + } + return 0; +} + +void FindNext() +{ + unsigned long curSel; + if ((curSel = (unsigned long)SendMessage(maindlg::hWndQuadList, LB_GETCURSEL, 0, 0)) == LB_ERR) return; + int direction; + if (SendMessage(finddlg::hWndDownOpt,BM_GETCHECK,0,0) == BST_CHECKED) + { + direction = FIND_DOWN; + } + else if (SendMessage(finddlg::hWndUpOpt,BM_GETCHECK,0,0) == BST_CHECKED) + { + direction = FIND_UP; + } + unsigned long retVal = FIND_ERR; + if (SendMessage(finddlg::hWndQuadIDOpt,BM_GETCHECK,0,0) == BST_CHECKED) //Quad and ID Search + { + std::wstring idtxt = GetTextFromHWND(finddlg::hWndIDTxt); + unsigned long idval = GetValueFromHWND(finddlg::hWndIDTxt); + char quadstr[5]; + unsigned char len = (unsigned char)SendMessageA(finddlg::hWndQuadTxt, WM_GETTEXT, (WPARAM)5,(LPARAM)quadstr); + quad quadtype; + if (len == 4) quadtype = ConvertStringToQuad(quadstr); + if (len == 4 && idtxt == L"") //Quad Only + { + retVal = dmmfile.findFromQuad_Type(quadtype, curSel, direction, GETQUAD_QUADORDERSORT); + } + else if (idtxt != L"" && len == 0) //ID Only + { + retVal = dmmfile.findFromQuad_ID(idval, curSel, direction, GETQUAD_QUADORDERSORT); + } + else if (len == 4 && idtxt != L"") //Both + { + SQuadID quadid; + quadid.type = quadtype; + quadid.id = idval; + retVal = dmmfile.findFromQuad_QuadID(quadid, curSel, direction, GETQUAD_QUADORDERSORT); + } + } + else if (SendMessage(finddlg::hWndStrOpt,BM_GETCHECK,0,0) == BST_CHECKED) // String Search + { + std::wstring str = GetTextFromHWND(finddlg::hWndStrTxt); + retVal = dmmfile.findFromQuad_String(str, curSel, direction, GETQUAD_QUADORDERSORT); + } + /*std::wstringstream ss; + ss << retVal; + MessageBox(finddlg::hWnd, ss.str().c_str(), L"", MB_OK);*/ + if (retVal == FIND_ERR) return; + SendMessage(maindlg::hWndQuadList, LB_SETCURSEL, retVal, 0); + ChangeQuad(); + return; +} \ No newline at end of file diff --git a/pencil++2/globalconstants.h b/pencil++2/globalconstants.h new file mode 100644 index 0000000..3184d3a --- /dev/null +++ b/pencil++2/globalconstants.h @@ -0,0 +1,31 @@ +/* 3DMM Pencil++ 2 + Copyright (C) 2005 Frankie Weindel */ + +//Main Dialog Resize Constants +#define MAINDLG_MIN_WIDTH 800 +#define MAINDLG_MIN_HEIGHT 500 + +//Main Dialog Ect +#define MAINDLG_TITLE L"3DMM Pencil++ 2 Beta 3" +#define MAINDLG_TITLE_ L"3DMM Pencil++ 2 Beta 3 - " + + +//Error Stings +#define QUAD_FOUR_CHARACTERS L"Quad must be 4 characters" +#define QUAD_UNICODE_USED L"You cannot use any unicode characters in the quad type" +#define SIGNATURE_FOUR_CHARACTERS L"Signature must be 4 characters" +#define SIGNATURE_UNICODE_USED L"You cannot use any unicode characters in the signature" +#define QUAD_REFERENCED_ITSELF L"Quad cannot reference itself!" +#define QUAD_REFID_EXISTS L"Another reference with the same quad and ref id already exists" +#define QUAD_QUADID_EXISTS L"Quad and ID already exist" + +//DO NOT CHANGE BELOW LINE// +#define TAB_NONE 0 +#define TAB_REFERENCES 1 +#define TAB_VIEWEDIT 2 +#define TAB_VIEWHEX 3 + +//Changes Made returns +#define CHANGE_CANCEL 0 +#define CHANGE_YES 1 +#define CHANGE_NO 2 \ No newline at end of file diff --git a/pencil++2/headerdlg.cpp b/pencil++2/headerdlg.cpp new file mode 100644 index 0000000..2db35f9 --- /dev/null +++ b/pencil++2/headerdlg.cpp @@ -0,0 +1,99 @@ +/* 3DMM Pencil++ 2 + Copyright (C) 2005 Frankie Weindel */ + +#include "pencil.h" + +namespace editheader +{ + HWND hWnd; + HWND hWndSignature; + HWND hWndUnk1; + HWND hWndUnk2; + HWND hWndStringType; +}; + +LRESULT CALLBACK EditHeaderDlgProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam) +{ + switch(msg) + { + case WM_INITDIALOG: + { + editheader::hWnd = hWnd; + editheader::hWndSignature = GetDlgItem(hWnd,IDC_SIGNATURE); + editheader::hWndUnk1 = GetDlgItem(hWnd, IDC_UNK1); + editheader::hWndUnk2 = GetDlgItem(hWnd, IDC_UNK2); + editheader::hWndStringType = GetDlgItem(hWnd, IDC_STRTYPE); + SendMessage(editheader::hWndStringType, CB_ADDSTRING, 0, (LPARAM)L"ASCII"); + SendMessage(editheader::hWndStringType, CB_ADDSTRING, 0, (LPARAM)L"Unicode"); + SendMessage(editheader::hWndSignature, EM_SETLIMITTEXT, (WPARAM)4, (LPARAM)0); + + //Load data + SendMessage(editheader::hWndSignature, WM_SETTEXT, 0, (LPARAM)ConvertQuadToString(dmmfile.header.signature).c_str()); + std::wstringstream ss; + ss << dmmfile.header.unk1; + SendMessage(editheader::hWndUnk1, WM_SETTEXT, 0, (LPARAM)ss.str().c_str()); + ss.str(L""); + ss << dmmfile.header.unk2; + SendMessage(editheader::hWndUnk2, WM_SETTEXT, 0, (LPARAM)ss.str().c_str()); + switch(dmmfile.header.magicnum) + { + case 0x03030001: + SendMessage(editheader::hWndStringType,CB_SETCURSEL,(WPARAM) 0 ,(LPARAM) 0 ); + break; + case 0x05050001: + SendMessage(editheader::hWndStringType,CB_SETCURSEL,(WPARAM) 1 ,(LPARAM) 0 ); + break; + default: + dmmfile.header.magicnum = 0x03030001; + dmmfile.header.magicnum = 0x03030001; + SendMessage(editheader::hWndStringType,CB_SETCURSEL,(WPARAM) 0 ,(LPARAM) 0 ); + } + return 1; + } + break; + case WM_QUIT: + case WM_CLOSE: + EndDialog(hWnd,0); + break; + case WM_COMMAND: + switch(LOWORD(wParam)) + { + case IDOK: + { + wchar_t buffer[5]; + SendMessage(editheader::hWndSignature, WM_GETTEXT, (WPARAM)4+1, (LPARAM)buffer); + //Check for bad QUAD + if (_GetStringType(buffer) == STR_UNICODE) + { + MessageBox(refchild::hWnd, SIGNATURE_UNICODE_USED, L"Error", MB_OK | MB_ICONERROR); + return 0; + } + if (wcslen(buffer) != 4) + { + MessageBox(refchild::hWnd,SIGNATURE_FOUR_CHARACTERS, L"Error", MB_OK | MB_ICONERROR); + return 0; + } + dmmfile.header.signature = ConvertStringToQuad(buffer); + dmmfile.header.unk1 = (short)GetValueFromHWND(editheader::hWndUnk1); + dmmfile.header.unk2 = (short)GetValueFromHWND(editheader::hWndUnk2); + switch (SendMessage(editheader::hWndStringType,CB_GETCURSEL,(WPARAM) 0 ,(LPARAM) 0 )) + { + case 0: + dmmfile.header.magicnum = MN_1033; + break; + case 1: + dmmfile.header.magicnum = MN_1055; + break; + } + EndDialog(hWnd,0); + } + break; + case IDCANCEL: + EndDialog(hWnd,0); + break; + } + default:; + + } + return 0; +} \ No newline at end of file diff --git a/pencil++2/hex.h b/pencil++2/hex.h new file mode 100644 index 0000000..9c3aee2 --- /dev/null +++ b/pencil++2/hex.h @@ -0,0 +1,8 @@ +#ifndef _HEX_H +#define _HEX_H + +typedef wchar_t hexentry[3]; +#define HEXCODES { L"00", L"01", L"02", L"03", L"04", L"05", L"06", L"07", L"08", L"09", L"0A", L"0B", L"0C", L"0D", L"0E", L"0F", L"10", L"11", L"12", L"13", L"14", L"15", L"16", L"17", L"18", L"19", L"1A", L"1B", L"1C", L"1D", L"1E", L"1F", L"20", L"21", L"22", L"23", L"24", L"25", L"26", L"27", L"28", L"29", L"2A", L"2B", L"2C", L"2D", L"2E", L"2F", L"30", L"31", L"32", L"33", L"34", L"35", L"36", L"37", L"38", L"39", L"3A", L"3B", L"3C", L"3D", L"3E", L"3F", L"40", L"41", L"42", L"43", L"44", L"45", L"46", L"47", L"48", L"49", L"4A", L"4B", L"4C", L"4D", L"4E", L"4F", L"50", L"51", L"52", L"53", L"54", L"55", L"56", L"57", L"58", L"59", L"5A", L"5B", L"5C", L"5D", L"5E", L"5F", L"60", L"61", L"62", L"63", L"64", L"65", L"66", L"67", L"68", L"69", L"6A", L"6B", L"6C", L"6D", L"6E", L"6F", L"70", L"71", L"72", L"73", L"74", L"75", L"76", L"77", L"78", L"79", L"7A", L"7B", L"7C", L"7D", L"7E", L"7F", L"80", L"81", L"82", L"83", L"84", L"85", L"86", L"87", L"88", L"89", L"8A", L"8B", L"8C", L"8D", L"8E", L"8F", L"90", L"91", L"92", L"93", L"94", L"95", L"96", L"97", L"98", L"99", L"9A", L"9B", L"9C", L"9D", L"9E", L"9F", L"A0", L"A1", L"A2", L"A3", L"A4", L"A5", L"A6", L"A7", L"A8", L"A9", L"AA", L"AB", L"AC", L"AD", L"AE", L"AF", L"B0", L"B1", L"B2", L"B3", L"B4", L"B5", L"B6", L"B7", L"B8", L"B9", L"BA", L"BB", L"BC", L"BD", L"BE", L"BF", L"C0", L"C1", L"C2", L"C3", L"C4", L"C5", L"C6", L"C7", L"C8", L"C9", L"CA", L"CB", L"CC", L"CD", L"CE", L"CF", L"D0", L"D1", L"D2", L"D3", L"D4", L"D5", L"D6", L"D7", L"D8", L"D9", L"DA", L"DB", L"DC", L"DD", L"DE", L"DF", L"E0", L"E1", L"E2", L"E3", L"E4", L"E5", L"E6", L"E7", L"E8", L"E9", L"EA", L"EB", L"EC", L"ED", L"EE", L"EF", L"F0", L"F1", L"F2", L"F3", L"F4", L"F5", L"F6", L"F7", L"F8", L"F9", L"FA", L"FB", L"FC", L"FD", L"FE", L"FF" } +void GetHex(BYTE *bytearray, unsigned long size, std::wstringstream *ss); + +#endif \ No newline at end of file diff --git a/pencil++2/ico.ico b/pencil++2/ico.ico new file mode 100644 index 0000000..7b195e5 Binary files /dev/null and b/pencil++2/ico.ico differ diff --git a/pencil++2/loader.cpp b/pencil++2/loader.cpp new file mode 100644 index 0000000..0914576 --- /dev/null +++ b/pencil++2/loader.cpp @@ -0,0 +1,203 @@ +/* 3DMM Pencil++ 2 + Copyright (C) 2005 Frankie Weindel */ + +#include "pencilclass.h" + +bool CPencil::open(std::wstring path) +{ + fpath = path; + mainfp = _wfopen(fpath.c_str(), L"rb"); + if (!mainfp) //file error + { + raiseError(PERROR_FOPEN); + return false; + } + if (fileIsOpen) { raiseError(PERROR_ALREADYOPENED); return false; } + if (scan()) + { + fileIsOpen = true; + fclose(mainfp); + return true; + } + else + { + fileIsOpen = false; + fclose(mainfp); + return false; + } +} + +bool CPencil::scan() +{ + if (!mainfp) { raiseError(PERROR_FOPEN); return false; } + rewind(mainfp); + FF_3dmmHeader head; + fread(&head,sizeof(FF_3dmmHeader),1,mainfp); if (ferror(mainfp)) { raiseError(PERROR_NOTVALID); return false; } + if (!CompareQuads(head.identifier, "2NHC") || head.filelen != head.filelen2 || FileSize(mainfp) != head.filelen || (head.magicnum != MN_1033 && head.magicnum != MN_1055)) + { + raiseError(PERROR_NOTVALID); + return false; + } + header.signature = head.signature; + header.unk1 = head.unk1; + header.unk2 = head.unk2; + header.magicnum = head.magicnum; + fgoto(mainfp,head.indexoffset); //Seek to index + FF_3dmmIndexHeader indexhead; //3DMM Index header struct + fread(&indexhead,sizeof(FF_3dmmIndexHeader),1,mainfp); //read index header + //Check format conditions + if (indexhead.FFFFFFFF != 0xFFFFFFFF || indexhead.unk20 != 20 || (indexhead.magicnum != MN_1033 && indexhead.magicnum != MN_1055)) + { + raiseError(PERROR_NOTVALID); + return false; + } + unsigned long quaddexoffset = ftell(mainfp); //Get offset to quaddex + + //Directory + fseek(mainfp,indexhead.quadindexlen,SEEK_CUR); //Seek to directory + FF_3dmmDirectoryEntry *directory = new FF_3dmmDirectoryEntry[indexhead.numsections]; + fread(directory,sizeof(FF_3dmmDirectoryEntry),indexhead.numsections,mainfp); //Read directory + + //Quads + for (unsigned int sectnum = 0; sectnum < indexhead.numsections; sectnum++) + { + fgoto(mainfp, head.indexoffset + 20 + directory[sectnum].offset); + unsigned int curpossect = 0; + FF_3dmmIndexQuad quaddata; + fread(&quaddata,sizeof(FF_3dmmIndexQuad),1,mainfp); + curpossect += sizeof(FF_3dmmIndexQuad); + if (curpossect > directory[sectnum].length) + { + raiseError(PERROR_NOTVALID); + return false; + } + SQuad *tempQuadSection = new SQuad; + tempQuadSection->temp.quadoffset = directory[sectnum].offset; + tempQuadSection->temp.quadsize = directory[sectnum].length; + + tempQuadSection->quadid.type = quaddata.type; + tempQuadSection->quadid.id = quaddata.id; + tempQuadSection->mode = quaddata.mode; + tempQuadSection->timesreferenced = quaddata.timesreferenced; + + //refs + FF_3dmmIndexReference *refs = new FF_3dmmIndexReference[quaddata.numreferences]; + fread(refs,sizeof(FF_3dmmIndexReference),quaddata.numreferences,mainfp); + curpossect += (sizeof(FF_3dmmIndexReference) * quaddata.numreferences); + if (curpossect > directory[sectnum].length) + { + raiseError(PERROR_NOTVALID); + return false; + } + //REFERENCES + tempQuadSection->references.quads = &quads; + for (int refnum = 0; refnum < quaddata.numreferences; refnum++) + { + tempQuadSection->references.addReference(refs[refnum]); + } + delete[] refs; + //tempQuadSection->quadoffset = directory[sectnum].offset; + //STRINGZ + if (curpossect + 3 <= directory[sectnum].length) //Possible String + { + unsigned short strtype; + fread(&strtype,sizeof(short),1,mainfp); + switch (strtype) + { + case 0x0303: //ASCII STRING + unsigned char strlen; + fread(&strlen,sizeof(char),1,mainfp); + curpossect += 3; + if (curpossect + strlen <= directory[sectnum].length) + { + char *str = new char[strlen + 1]; + fread(str,sizeof(char),strlen,mainfp); + str[strlen] = 0; + //fixstring(str); + //wchar_t *wstr = new wchar_t[strlen + 1]; + //ConvertStrToWStr(str,wstr); + tempQuadSection->string.setString(str); + + delete[] str; + //delete[] wstr; + //MessageBox(NULL,tempQuadSection->str.c_str(),L"DSFDS",MB_OK); + break; + } + goto defaultarea; + break; + case 0x0505: //UNICODE STRING + if (curpossect + 4 <= directory[sectnum].length) + { + unsigned short strlen; + fread(&strlen,sizeof(short),1,mainfp); + + curpossect += 4; + if (curpossect + (strlen * 2) <= directory[sectnum].length) + { + wchar_t *wstr = new wchar_t[strlen + 1]; + fread(wstr,sizeof(wchar_t),strlen,mainfp); + wstr[strlen] = 0; + tempQuadSection->string.setString(wstr); + //MessageBox(NULL,tempQuadSection->GetString().c_str(),L"DSFDS",MB_OK); + break; + } + + } + default: +defaultarea: + break; + } + } + //Get Section Data, and Import it + size_t sectionlen = (quaddata.seclength[2]<<16)|(quaddata.seclength[1]<<8)|quaddata.seclength[0]; + + fgoto(mainfp, quaddata.secoffset); + tempQuadSection->temp.sectionoffset = quaddata.secoffset; + tempQuadSection->temp.sectionsize = sectionlen; + BYTE *sectiondata = new BYTE[sectionlen]; + fread(sectiondata,sizeof(BYTE),sectionlen,mainfp); + tempQuadSection->section.setSectionData(sectiondata, (unsigned long)sectionlen); + + //delete[] sectiondata; + tempQuadSection->uniqueid = lastuniqueid++; + quads.push_back(tempQuadSection); + } + std::sort(quads.begin(), quads.end(), SectionOffsetSort()); + quadindexsort.setSortType(GETQUAD_QUADORDERSORT); + quadindexsort.addPointers(&quads); + directorysort.addPointers(&quads); + raiseError(PERROR_NONE); + return true; +} + +bool CPencil::close() +{ + if (fileIsOpen) + { + for (std::vector::iterator itr = quads.begin(); itr != quads.end(); itr++) + { + delete [] (*itr)->section.getSectionData(); + (*itr)->references.clearReferences(); + delete (*itr); + } + quads.clear(); + quadindexsort.clear(); + directorysort.clear(); + lastuniqueid = 0; + fpath.clear(); + //MessageBox(NULL,L"DSFDS",L"SDFDS",MB_OK); + fileIsOpen = false; + return true; + } + return false; +} +bool CPencil::createNew() +{ + if (fileIsOpen) { raiseError(PERROR_ALREADYOPENED); return false; } + header.magicnum = MN_1033; + header.signature = ConvertStringToQuad("CHMP"); + header.unk1 = 0x0005; + header.unk2 = 0x0004; + fileIsOpen = true; + return true; +} \ No newline at end of file diff --git a/pencil++2/loader.h b/pencil++2/loader.h new file mode 100644 index 0000000..e69de29 diff --git a/pencil++2/maindialog.cpp b/pencil++2/maindialog.cpp new file mode 100644 index 0000000..cbaa731 --- /dev/null +++ b/pencil++2/maindialog.cpp @@ -0,0 +1,584 @@ +/* 3DMM Pencil++ 2 + Copyright (C) 2005 Frankie Weindel */ + +#include "pencil.h" + +int currenttab; +bool tabrefloaded; +bool tabeditloaded; +bool tabhexloaded; + +TVHITTESTINFO tvht; +TV_INSERTSTRUCT tvinsert; +std::wstringstream ss2; + +unsigned long lastcursel; + +bool treeviewloaded; + +namespace maindlg +{ + HWND hWnd; + HWND hWndQuadList; + HWND hWndQuadTreeView; + HWND hWndMoveUpBtn; + HWND hWndMoveDownBtn; + HWND hWndAddQuadBtn; + HWND hWndRemoveQuadBtn; + HWND hWndQuadLbl; + HWND hWndIDLbl; + HWND hWndStrLbl; + HWND hWndQuadTxt; + HWND hWndIDTxt; + HWND hWndStrTxt; + HWND hWndTab; + HWND hWndSectDataBox; + HWND hWndOffLenLbl; + HWND hWndImportBtn; + HWND hWndExportBtn; + HWND hWndApplyBtn; + HMENU hMenu; +}; + +void SetStructureView(bool treeView) +{ + if (treeView) + { + //TreeView + //Hide List Box and Bottom Buttons + ShowWindow(maindlg::hWndQuadList, SW_HIDE); + ShowWindow(maindlg::hWndAddQuadBtn, SW_HIDE); + ShowWindow(maindlg::hWndRemoveQuadBtn, SW_HIDE); + ShowWindow(maindlg::hWndMoveDownBtn, SW_HIDE); + ShowWindow(maindlg::hWndMoveUpBtn, SW_HIDE); + + ShowWindow(maindlg::hWndQuadTreeView, SW_SHOW); //Show Tree View + treeviewloaded = true; + //Set Tree Function + } + else + { + //Regular View + ShowWindow(maindlg::hWndQuadTreeView, SW_HIDE); //Hide Tree View + + //Show List Box and Bottom Buttons + ShowWindow(maindlg::hWndQuadList, SW_SHOW); + ShowWindow(maindlg::hWndAddQuadBtn, SW_SHOW); + ShowWindow(maindlg::hWndRemoveQuadBtn, SW_SHOW); + ShowWindow(maindlg::hWndMoveDownBtn, SW_SHOW); + ShowWindow(maindlg::hWndMoveUpBtn, SW_SHOW); + treeviewloaded = false; + } +} + +void DoTreeView() +{ + int checkstate = CheckMenuItem(maindlg::hMenu, ID_EDIT_TREEVIEW, NULL); + if (checkstate == MF_CHECKED) + { + CheckMenuItem(maindlg::hMenu, ID_EDIT_TREEVIEW, MF_UNCHECKED); + SetStructureView(false); + } + else + { + CheckMenuItem(maindlg::hMenu, ID_EDIT_TREEVIEW, MF_CHECKED); + SetStructureView(true); + LoadTreeView(); + } +} +void LoadTreeView() +{ + SendMessage(maindlg::hWndQuadTreeView, TVM_SELECTITEM, TVGN_CARET, NULL); + TreeView_DeleteAllItems(maindlg::hWndQuadTreeView); + unsigned long numquads = dmmfile.getNumQuads(); + for (unsigned long quadnum = 0; quadnum < numquads; quadnum++) + { + SQuad quad = dmmfile.getQuad(quadnum, GETQUAD_QUADORDERSORT); + if (quad.timesreferenced == 0) + { + ss2.str(L""); + tvinsert.hParent=NULL; // top most level no need handle + tvinsert.hInsertAfter=TVI_ROOT; // work as root level + tvinsert.item.mask=TVIF_TEXT | TVIF_CHILDREN | TVIF_PARAM; + if (quad.string.getStringType() != STR_NONE) + ss2 << ConvertQuadToString(quad.quadid.type) << L" - " << quad.quadid.id << L" \"" << quad.string.getString() << L"\""; + else + ss2 << ConvertQuadToString(quad.quadid.type) << L" - " << quad.quadid.id; + wchar_t text[300]; + tvinsert.item.pszText=text; + wcscpy(tvinsert.item.pszText,ss2.str().c_str()); + tvinsert.item.lParam = quad.uniqueid; + if (quad.references.getNumReferences() > 0) + { + tvinsert.item.cChildren = 1; + } + else + { + tvinsert.item.cChildren = 0; + } + SendMessage(maindlg::hWndQuadTreeView,TVM_INSERTITEM,0,(LPARAM)&tvinsert); + + + } + } + + +} + +void SetTitle(std::wstring str) +{ + SendMessage(maindlg::hWnd, WM_SETTEXT, NULL, (LPARAM)str.c_str()); +} + + +bool ProcessMainResize(short width, short height) +{ + RECT clientrect; + GetClientRect(maindlg::hWnd, &clientrect); + short clientwidth = (short)clientrect.right; + short clientheight = (short)clientrect.bottom; + //42% Box + short listwidth = (short)(clientwidth * 0.42); + if (listwidth > 425) { listwidth = 425; } + ResizePosWindow(maindlg::hWndQuadList, 10, 10, listwidth, clientheight - 67); //QuadList Box + ResizePosWindow(maindlg::hWndQuadTreeView, 10, 10, listwidth, clientheight - 20); //Tab Window + //Button Width = 79x37 + //Buttom Gap Width = 11 + short buttonwidth = (listwidth - (3*11)) / 4; + ResizePosWindow(maindlg::hWndMoveUpBtn, 8, clientheight - 48, buttonwidth ,37); + ResizePosWindow(maindlg::hWndAddQuadBtn, 20 + buttonwidth, clientheight - 48, buttonwidth ,37); + ResizePosWindow(maindlg::hWndRemoveQuadBtn, 31 + (buttonwidth * 2), clientheight - 48, buttonwidth ,37); + ResizePosWindow(maindlg::hWndMoveDownBtn, 43 + (buttonwidth * 3), clientheight - 48, buttonwidth ,37); + + short afterlistx = listwidth + 19; + RePosWindow(maindlg::hWndQuadLbl, afterlistx, 14); + RePosWindow(maindlg::hWndQuadTxt, afterlistx, 29); + RePosWindow(maindlg::hWndIDLbl, afterlistx, 52); + RePosWindow(maindlg::hWndIDTxt, afterlistx, 68); + RePosWindow(maindlg::hWndStrLbl, afterlistx, 91); + RePosWindow(maindlg::hWndStrTxt, afterlistx, 107); + + + ResizePosWindow(maindlg::hWndTab, afterlistx, 137, clientwidth - afterlistx - 10, clientheight - 137 - 87); //Tab Window + ResizeWindow(refchild::hWnd, clientwidth - afterlistx - 20, clientheight - 137 - 117); + ResizeWindow(viewhexchild::hWnd, clientwidth - afterlistx - 20, clientheight - 137 - 117); + if (hWndEditor != NULL && tabeditloaded == true) + { + ResizeWindow(hWndEditor, clientwidth - afterlistx - 20, clientheight - 137 - 117); + } + + ResizePosWindow(maindlg::hWndSectDataBox, afterlistx,clientheight - 77, clientwidth - afterlistx - 82, 67); + RECT rectsectbox; + rectsectbox.top = clientheight - 77; rectsectbox.bottom = (rectsectbox.top + 67); rectsectbox.left = afterlistx; rectsectbox.right = rectsectbox.left + (clientwidth - afterlistx - 82); + ResizePosWindow(maindlg::hWndOffLenLbl, (short)rectsectbox.left + 10,(short)rectsectbox.top + 16, rectsectbox.right - rectsectbox.left - 190,50); + RePosWindow(maindlg::hWndImportBtn, (short)rectsectbox.right - 176,(short)rectsectbox.top + 13); + RePosWindow(maindlg::hWndExportBtn, (short)rectsectbox.right - 91,(short)rectsectbox.top + 13); + RePosWindow(maindlg::hWndApplyBtn, (short)clientwidth - 72,(short)rectsectbox.top); + InvalidateRect(maindlg::hWndOffLenLbl, NULL, true); + InvalidateRect(maindlg::hWndImportBtn, NULL, true); + InvalidateRect(maindlg::hWndExportBtn, NULL, true); + InvalidateRect(maindlg::hWndApplyBtn, NULL, true); + + return true; +} + +LRESULT CALLBACK WndProc( HWND hWnd, // Handle For This Window + UINT uMsg, // Message For This Window + WPARAM wParam, // Additional Message Information + LPARAM lParam) // Additional Message Information +{ + + //MessageBox(hWnd,"SDFDS","SDFDS",MB_OK); + switch (uMsg) // Check For Windows Messages + { + default: + + return DefDlgProc(hWnd,uMsg,wParam,lParam); + } + + + return 0; +} + +LRESULT CALLBACK MainDlgProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam) +{ + switch(msg) + { + case WM_INITDIALOG: + { + //Get all Dialog Item Handles + maindlg::hWnd = hWnd; + maindlg::hWndQuadList = GetDlgItem(hWnd, IDC_QUAD_LIST); + maindlg::hWndQuadTreeView = GetDlgItem(hWnd, IDC_TREEVIEW); + maindlg::hWndMoveUpBtn = GetDlgItem(hWnd, IDC_SECTION_MVUP); + maindlg::hWndMoveDownBtn = GetDlgItem(hWnd, IDC_SECTION_MVDN); + maindlg::hWndAddQuadBtn = GetDlgItem(hWnd, IDC_SECTION_ADD); + maindlg::hWndRemoveQuadBtn = GetDlgItem(hWnd, IDC_SECTION_DELETE); + maindlg::hWndQuadLbl = GetDlgItem(hWnd, IDC_QUAD_LBL); + maindlg::hWndIDLbl = GetDlgItem(hWnd, IDC_ID_LBL); + maindlg::hWndStrLbl = GetDlgItem(hWnd, IDC_STRING_LBL); + maindlg::hWndQuadTxt = GetDlgItem(hWnd, IDC_SECTIONEDIT_QUADTYPE); + maindlg::hWndIDTxt = GetDlgItem(hWnd, IDC_SECTIONEDIT_ID); + maindlg::hWndStrTxt = GetDlgItem(hWnd, IDC_SECTIONEDIT_STRING); + maindlg::hWndTab = GetDlgItem(hWnd, IDC_TAB1); + maindlg::hWndSectDataBox = GetDlgItem(hWnd, IDC_SECTBOX); + maindlg::hWndOffLenLbl = GetDlgItem(hWnd, IDC_INF_SECT_DATA); + maindlg::hWndImportBtn = GetDlgItem(hWnd, IDC_SECT_IMPORT); + maindlg::hWndExportBtn = GetDlgItem(hWnd, IDC_SECT_EXPORT); + maindlg::hWndApplyBtn = GetDlgItem(hWnd, IDC_APPLY_CHANGE); + maindlg::hMenu = GetMenu(hWnd); + + //Create Tab Items + HWND hWndTabControl = GetDlgItem(hWnd , IDC_TAB1); + TCITEM tci1, tci2, tci3; + tci1.mask = TCIF_TEXT; + tci1.pszText = L"View Hex"; + tci1.cchTextMax = (int)wcslen(L"View Hex") + 1; + tci1.iImage = -1; + tci1.lParam = 0; + tci2.mask = TCIF_TEXT; + tci2.pszText = L"View/Edit"; + tci2.cchTextMax = (int)wcslen(L"View/Edit") + 1; + tci2.iImage = -1; + tci2.lParam = 0; + tci3.mask = TCIF_TEXT; + tci3.pszText = L"References"; + tci3.cchTextMax = (int)wcslen(L"References") + 1; + tci3.iImage = -1; + tci3.lParam = 0; + TabCtrl_InsertItem(hWndTabControl, 0, & tci1); //Insert Tab 1 + TabCtrl_InsertItem(hWndTabControl, 0, & tci2); //Insert Tab 2 + TabCtrl_InsertItem(hWndTabControl, 0, & tci3); //Insert Tab 2 + TabCtrl_SetCurSel(hWndTabControl,0); + currenttab = TAB_REFERENCES; + refchild::hWnd = CreateDialog(hInstance, MAKEINTRESOURCE(IDD_REFERENCES), maindlg::hWndTab, (DLGPROC)RefDlgProc); + RePosWindow(refchild::hWnd, 5,23); + viewhexchild::hWnd = CreateDialog(hInstance, MAKEINTRESOURCE(IDD_VIEW_HEX), maindlg::hWndTab, (DLGPROC)ViewHexDlgProc); + RePosWindow(viewhexchild::hWnd, 5,23); + ShowWindow(refchild::hWnd, SW_SHOW); + SetStructureView(false); + CheckMenuItem(maindlg::hMenu, ID_EDIT_TREEVIEW, MF_UNCHECKED); + SetTitle(MAINDLG_TITLE_ + std::wstring(L"Untitled")); + return 1; + } + break; + + case WM_COMMAND: + switch(LOWORD(wParam)) + { + case ID_EDIT_FIND1: + if (finddlg::hWnd == NULL) + { + DialogBox(NULL,MAKEINTRESOURCE(IDD_FIND),NULL,(DLGPROC)FindDlgProc); + } + else + { + BringWindowToTop(finddlg::hWnd); + } + break; + case ID_EDIT_TREEVIEW: + DoTreeView(); + break; + case ID_FILE_NEW1: + { + HANDLE hThread = GetCurrentThread(); + SetThreadPriority(hThread, THREAD_PRIORITY_HIGHEST); + dmmfile.close(); + dmmfile.createNew(); + ListQuads(); + SetTitle(MAINDLG_TITLE_ + std::wstring(L"Untitled")); + SetThreadPriority(hThread, THREAD_PRIORITY_NORMAL); + break; + } + case ID_FILE_OPEN1: + { + HANDLE hThread = GetCurrentThread(); + SetThreadPriority(hThread, THREAD_PRIORITY_HIGHEST); + std::wstring fpath; + std::wstring ftitle; + if (!ShowOpenDlg(hWnd,L"Open 3DMM File", L"3DMM Files (*.3cn;*.3th;*.chk;*.3mm)|*.3cn;*.3th;*.chk;*.3mm|N3DMM Files (*.nth;*.nmm)|*.nth;*.nmm|",&fpath,&ftitle)) break; + dmmfile.close(); + if (dmmfile.open(fpath)) + { + ListQuads(); + if (treeviewloaded) + { + LoadTreeView(); + } + } + else { MessageBox(hWnd, dmmfile.getLastErrorText().c_str(), L"Error", MB_OK | MB_ICONEXCLAMATION); } + SetThreadPriority(hThread, THREAD_PRIORITY_NORMAL); + SetTitle(MAINDLG_TITLE_ + ftitle); + } + break; + case ID_FILE_SAVE1: + { + if (!dmmfile.save()) + { + if (dmmfile.getLastError() != PERROR_NOFPATHEXISTS) break; + } else break; + } + case ID_FILE_SAVEAS1: + { + std::wstring fpath; + std::wstring ftitle; + ShowSaveDlg(hWnd, L"Save 3DMM File", L"3DMM 3CN Data Files (*.3cn)|*.3cn|3DMM 3TH Data Files (*.3th)|*.3th|3DMM CHK Data Files (*.chk)|*.chk|3DMM Movie Files (*.3mm)|*.3mm|N3DMM NTH Data Files (*.nth)|*.nth|N3DMM Movie Files (*.nmm)|*.nmm|", + L"",&fpath, &ftitle); + dmmfile.saveAs(fpath, false); + SetTitle(MAINDLG_TITLE_ + ftitle); + break; + } + case ID_FILE_EXIT: + { + dmmfile.close(); + SendMessage(hWnd,WM_CLOSE,0,0); + break; + } + case ID_HEADERINFO: + DialogBox(hInstance,MAKEINTRESOURCE(IDD_HEADER),hWnd,(DLGPROC)EditHeaderDlgProc); + break; + case ID_HELP_ABOUT: + ShellAbout(maindlg::hWnd,L"3DMM Pencil++ 2 Beta 2", L"Yet another beta and still no real about box...", LoadIcon(hInstance, MAKEINTRESOURCE(IDI_ICON2))); + break; + case IDC_QUAD_LIST: + switch (HIWORD(wParam)) + { + case LBN_SELCHANGE: + ChangeQuad(); + break; + } + break; + case IDC_SECTION_ADD: + AddQuad(); + break; + case IDC_SECTION_DELETE: + RemoveQuad(); + break; + case IDC_SECTION_MVDN: + MoveQuadDOWN(); + break; + case IDC_SECTION_MVUP: + MoveQuadUP(); + break; + case IDC_APPLY_CHANGE: + ApplyChanges(); + break; + case IDC_SECT_EXPORT: + ExportSection(); + break; + case IDC_SECT_IMPORT: + ImportSection(); + break; + //CHANGES MADE + case IDC_SECTIONEDIT_STRING: //STRING EDIT BOX + switch(HIWORD(wParam)) + { + case EN_CHANGE: //Change + ChangeMade(); + break; + } + break; + case IDC_SECTIONEDIT_QUADTYPE: //QUAD EDIT BOX + switch(HIWORD(wParam)) + { + case EN_CHANGE: //Change + ChangeMade(); + break; + } + break; + case IDC_SECTIONEDIT_ID: //ID EDIT BOX + switch(HIWORD(wParam)) + { + case EN_CHANGE: //Change + ChangeMade(); + break; + } + break; + } + break; + case WM_QUIT: + case WM_CLOSE: + //dmmfile.CloseFile(); + DestroyWindow(hWnd); + PostQuitMessage(0); + break; + case WM_SIZE: + { + short newWidth = LOWORD(lParam); + short newHeight = HIWORD(lParam); + SetWindowLong(hWnd,DWL_MSGRESULT,ProcessMainResize(newWidth, newHeight)); + return true; + } + case WM_SIZING: + { + RECT *sizerect = (RECT*)lParam; + short width = short(sizerect->right - sizerect->left); + short height = short(sizerect->bottom - sizerect->top); + + RECT dlgrect; + GetWindowRect(hWnd, &dlgrect); + + if (width < MAINDLG_MIN_WIDTH) + { + sizerect->left = dlgrect.left; + sizerect->right = sizerect->left + MAINDLG_MIN_WIDTH; + } + if (height < MAINDLG_MIN_HEIGHT) + { + sizerect->top = dlgrect.top; + sizerect->bottom = sizerect->top + MAINDLG_MIN_HEIGHT; + } + SetWindowLong(hWnd,DWL_MSGRESULT,true); + return true; + } + case WM_NOTIFY: + switch(LOWORD(wParam)) + { + case IDC_TREEVIEW: + if (((LPNMTREEVIEW)lParam)->hdr.code == TVN_SELCHANGED) + { + TVITEMEX item; + memset(&item,0,sizeof(item)); + item.hItem = ((LPNMTREEVIEW)lParam)->itemNew.hItem; + item.mask = TVIF_PARAM; + if (TreeView_GetItem(maindlg::hWndQuadTreeView,&item)) + { + unsigned long quadnum = dmmfile.getQuadNum(item.lParam, GETQUAD_QUADORDERSORT); + SendMessage(maindlg::hWndQuadList, LB_SETCURSEL,(WPARAM)quadnum,0); + ChangeQuad(); + } + } + else if(((LPNMTREEVIEW)lParam)->hdr.code == TVN_ITEMEXPANDED && ((LPNMTREEVIEW)lParam)->action == TVE_COLLAPSE) // if code == NM_CLICK - Single click on an item + { + HTREEITEM ecchiITEM = ((LPNMTREEVIEW)lParam)->itemNew.hItem; + HTREEITEM child = TreeView_GetChild(maindlg::hWndQuadTreeView, ecchiITEM); + while (child != NULL) + { + TreeView_DeleteItem(maindlg::hWndQuadTreeView, child); + child = TreeView_GetChild(maindlg::hWndQuadTreeView, ecchiITEM); + } + + } + else if(((LPNMTREEVIEW)lParam)->hdr.code == TVN_ITEMEXPANDING && ((LPNMTREEVIEW)lParam)->action == TVE_EXPAND) // if code == NM_CLICK - Single click on an item + { + TVITEMEX item; + memset(&item,0,sizeof(item)); + item.hItem = ((LPNMTREEVIEW)lParam)->itemNew.hItem; + item.mask = TVIF_PARAM; + + + if (TreeView_GetItem(maindlg::hWndQuadTreeView,&item)) + { + unsigned long uniqueid; + uniqueid = (unsigned long)item.lParam; + //char test[255]; + //wsprintf(test,"%i",ff3dmm.dmmIndex[quadNum].refsDisplayed); + //MessageBox(hWndDlg,test,"tojtss",MB_OK); + //CHECK IF REFS HAVE BEEN ALREADY DISPLAYED + + //FIND THE QUAD NUM OF ALL REFERENCES AND DISPLAY THEM IN THE LIST + SQuad quadparent; + dmmfile.getQuad(uniqueid, &quadparent); + std::vector references = quadparent.references.getReferences(); + for(std::vector ::iterator refItr = references.begin();refItr != references.end();refItr++) + { + SQuad quad; + if (dmmfile.getQuad(refItr->type, refItr->id, &quad)) + { + tvinsert.hParent=item.hItem; // top most level no need handle + tvinsert.hInsertAfter=TVI_LAST; + tvinsert.item.mask=TVIF_TEXT | TVIF_CHILDREN | TVIF_PARAM; + tvinsert.item.lParam = quad.uniqueid; + if (quad.references.getNumReferences() > 0) + { + tvinsert.item.cChildren = 1; + } + else + { + tvinsert.item.cChildren = 0; + } + wchar_t text[300]; + ss2.str(L""); + if (quad.string.getStringType()) + { + ss2 << ConvertQuadToString(quad.quadid.type) << L" " << quad.quadid.id << L":" << refItr->refid << L" \"" << quad.string.getString() << L"\""; + } + else + { + ss2 << ConvertQuadToString(quad.quadid.type) << L" " << quad.quadid.id << L":" << refItr->refid; + } + + + //MessageBox(hWndDlg,test,"test",MB_OK); + tvinsert.item.pszText=text; + wcscpy(tvinsert.item.pszText,ss2.str().c_str()); + SendMessage(maindlg::hWndQuadTreeView,TVM_INSERTITEM,0,(LPARAM)&tvinsert); + //goto outFor; + } + + } + } + } + break; + case IDC_TAB1: + HWND hWndTabControl = GetDlgItem(hWnd,IDC_TAB1); + int cursel = TabCtrl_GetCurSel(hWndTabControl); + if (((LPNMHDR)lParam)->code == TCN_SELCHANGING) + { + if (quadselectmode) + { + SetWindowLong(hWnd,DWL_MSGRESULT,true); + return true; + } + switch (cursel) + { + case 0: + ShowWindow(refchild::hWnd,SW_HIDE); + break; + case 1: + ShowWindow(hWndEditor,SW_HIDE); + break; + case 2: + ShowWindow(viewhexchild::hWnd,SW_HIDE); + break; + } + currenttab = TAB_NONE; + SetWindowLong(hWnd,DWL_MSGRESULT,false); + return true; + } + else if (((LPNMHDR)lParam)->code == TCN_SELCHANGE) + { + switch (cursel) + { + case 0: + if (!tabrefloaded) + { + DisplayReferences(curquad.quadid, &curquad.references); + } + ShowWindow(refchild::hWnd,SW_SHOW); + currenttab = TAB_REFERENCES; + break; + case 1: + if (!tabeditloaded) + { + DisplayEditor(); + } + ShowWindow(hWndEditor,SW_SHOW); + currenttab = TAB_VIEWEDIT; + break; + case 2: + if (!tabhexloaded) + { + SetViewHex(); + } + ShowWindow(viewhexchild::hWnd,SW_SHOW); + currenttab = TAB_VIEWHEX; + break; + } + } + } + default:; + //MessageBox(hWnd, L"EWFGEW", L"EWFEW", MB_OK); + } + return 0; +} \ No newline at end of file diff --git a/pencil++2/modifyfilestructure.cpp b/pencil++2/modifyfilestructure.cpp new file mode 100644 index 0000000..c840741 --- /dev/null +++ b/pencil++2/modifyfilestructure.cpp @@ -0,0 +1,302 @@ +/* 3DMM Pencil++ 2 + Copyright (C) 2005 Frankie Weindel */ + +#include "pencil.h" + +SQuadID addquad; + +bool curSecDataIsNew = false; + +LRESULT CALLBACK AddQuadDlgProc(HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam) +{ + switch(Msg) + { + case WM_INITDIALOG: + SendDlgItemMessage(hWnd, IDC_QUADTYPE, EM_SETLIMITTEXT, (WPARAM)4, (LPARAM)0); + break; + case WM_CLOSE: + case WM_QUIT: + EndDialog(hWnd,0); + break; + case WM_COMMAND: + switch(LOWORD(wParam)) + { + case IDOK: + { + wchar_t buffer[5]; + SendMessage(GetDlgItem(hWnd, IDC_QUADTYPE), WM_GETTEXT, (WPARAM)4+1, (LPARAM)buffer); + //Check for bad QUAD + if (_GetStringType(buffer) == STR_UNICODE) + { + MessageBox(refchild::hWnd, QUAD_UNICODE_USED, L"Error", MB_OK | MB_ICONERROR); + return 0; + } + if (wcslen(buffer) != 4) + { + MessageBox(refchild::hWnd,QUAD_FOUR_CHARACTERS, L"Error", MB_OK | MB_ICONERROR); + return 0; + } + SQuadID newquad; + newquad.type = ConvertStringToQuad(buffer); + newquad.id = GetValueFromHWND(GetDlgItem(hWnd, IDC_QUADID)); + if (dmmfile.getQuad(newquad, NULL)) + { + MessageBox(refchild::hWnd,QUAD_QUADID_EXISTS, L"Error", MB_OK | MB_ICONERROR); + return 0; + } + addquad = newquad; + EndDialog(hWnd,1); + } + break; + case IDCANCEL: + EndDialog(hWnd,0); + break; + } + break; + } + return 0; +} + +void MoveQuadUP() +{ + unsigned long cursel = (unsigned long)SendMessage(maindlg::hWndQuadList, LB_GETCURSEL, 0, 0); + if (cursel == 0) return; + if (cursel == LB_ERR) return; + unsigned long uniqueid = (unsigned long)SendMessage(maindlg::hWndQuadList, LB_GETITEMDATA, cursel, 0); + if (!dmmfile.moveQuadUp(uniqueid)) return; + + unsigned short textlen = (unsigned short)SendMessage(maindlg::hWndQuadList,LB_GETTEXTLEN, (WPARAM)cursel, 0); + wchar_t *strhold = new wchar_t[textlen + 1]; + SendMessage(maindlg::hWndQuadList,LB_GETTEXT, (WPARAM)cursel, (LPARAM)strhold); + strhold[textlen] = 0; + SendMessage(maindlg::hWndQuadList,LB_DELETESTRING,(WPARAM)cursel, 0); + unsigned long listnum = (unsigned long)SendMessage(maindlg::hWndQuadList, LB_INSERTSTRING, cursel - 1,(LPARAM) strhold); + SendMessage(maindlg::hWndQuadList, LB_SETITEMDATA, listnum,(LPARAM)uniqueid); + SendMessage(maindlg::hWndQuadList, LB_SETCURSEL, (WPARAM)listnum, 0); + delete [] strhold; +} + +void MoveQuadDOWN() +{ + unsigned long cursel = (unsigned long)SendMessage(maindlg::hWndQuadList, LB_GETCURSEL, 0, 0); + unsigned long numitems = (unsigned long)SendMessage(maindlg::hWndQuadList, LB_GETCOUNT, 0, 0); + if (cursel >= numitems - 1) return; + if (cursel == LB_ERR) return; + unsigned long uniqueid = (unsigned long)SendMessage(maindlg::hWndQuadList, LB_GETITEMDATA, cursel, 0); + if (!dmmfile.moveQuadDown(uniqueid)) return; + + unsigned short textlen = (unsigned short)SendMessage(maindlg::hWndQuadList,LB_GETTEXTLEN, (WPARAM)cursel, 0); + wchar_t *strhold = new wchar_t[textlen + 1]; + SendMessage(maindlg::hWndQuadList,LB_GETTEXT, (WPARAM)cursel, (LPARAM)strhold); + strhold[textlen] = 0; + SendMessage(maindlg::hWndQuadList,LB_DELETESTRING,(WPARAM)cursel, 0); + unsigned long listnum = (unsigned long)SendMessage(maindlg::hWndQuadList, LB_INSERTSTRING, cursel + 1,(LPARAM) strhold); + SendMessage(maindlg::hWndQuadList, LB_SETITEMDATA, listnum,(LPARAM)uniqueid); + SendMessage(maindlg::hWndQuadList, LB_SETCURSEL, (WPARAM)listnum, 0); + delete [] strhold; +} + +void RemoveQuad() +{ + unsigned long cursel = (unsigned long)SendMessage(maindlg::hWndQuadList, LB_GETCURSEL, 0, 0); + if (cursel == LB_ERR) return; + unsigned long uniqueid = (unsigned long)SendMessage(maindlg::hWndQuadList, LB_GETITEMDATA, cursel, 0); + if (!dmmfile.removeQuad(uniqueid)) return; + SendMessage(maindlg::hWndQuadList,LB_DELETESTRING,(WPARAM)cursel, 0); + unsigned long numitems = (unsigned long)SendMessage(maindlg::hWndQuadList, LB_GETCOUNT, (WPARAM)cursel,0); + if (cursel >= numitems) cursel = numitems - 1; + SendMessage(maindlg::hWndQuadList, LB_SETCURSEL, (WPARAM)cursel,0); + ChangeQuad(); +} + +void AddQuad() +{ + if (!DialogBox(hInstance, MAKEINTRESOURCE(IDD_DIALOG_ADDQUAD) ,maindlg::hWnd, (DLGPROC)AddQuadDlgProc)) return; + unsigned long cursel = (unsigned long)SendMessage(maindlg::hWndQuadList, LB_GETCURSEL, 0, 0) + 1; + if (cursel == LB_ERR) cursel = 0; + SQuad *newquad = new SQuad; + newquad->quadid = addquad; + newquad->mode = 0; + unsigned long uniqueid; + if ((uniqueid = dmmfile.addQuad(newquad,cursel)) == ERROR_LNG) return; + std::wstringstream ss; + ss << ConvertQuadToString(newquad->quadid.type) << L" - " << newquad->quadid.id; + unsigned long listnum = (unsigned long)SendMessage(maindlg::hWndQuadList, LB_INSERTSTRING, cursel,(LPARAM) ss.str().c_str()); + SendMessage(maindlg::hWndQuadList, LB_SETITEMDATA, listnum,(LPARAM)uniqueid); + SendMessage(maindlg::hWndQuadList, LB_SETCURSEL, (WPARAM)cursel, 0); + ChangeQuad(); +} + +void RemoveReference() +{ + unsigned long cursel = (unsigned long)SendMessage(refchild::hWndRefList, LB_GETCURSEL, 0, 0); + if (cursel == LB_ERR) return; + SendMessage(refchild::hWndRefList, LB_DELETESTRING, (WPARAM)cursel,0); + curquad.references.removeReference((unsigned short)cursel); + unsigned long numitems = (unsigned long)SendMessage(refchild::hWndRefList, LB_GETCOUNT, 0,0); + if (cursel >= numitems) cursel = numitems - 1; + SendMessage(refchild::hWndRefList, LB_SETCURSEL, (WPARAM)cursel,0); + ChangeMade(); +} + +void AddReference() +{ + wchar_t buffer[5]; + SendMessage(refchild::hWndQuadTxt, WM_GETTEXT, (WPARAM)4+1, (LPARAM)buffer); + //Check for bad QUAD + if (_GetStringType(buffer) == STR_UNICODE) + { + MessageBox(refchild::hWnd, QUAD_UNICODE_USED, L"Error", MB_OK | MB_ICONERROR); + return; + } + if (wcslen(buffer) != 4) + { + MessageBox(refchild::hWnd, QUAD_FOUR_CHARACTERS, L"Error", MB_OK | MB_ICONERROR); + return; + } + /////////////////////////// + FF_3dmmIndexReference newref; + newref.type = ConvertStringToQuad(buffer); + newref.id = GetValueFromHWND(refchild::hWndIDTxt); + newref.refid = GetValueFromHWND(refchild::hWndRefIDTxt); + if (curquad.quadid.type == newref.type && curquad.quadid.id == newref.id) + { + MessageBox(refchild::hWnd, QUAD_REFERENCED_ITSELF, L"Error", MB_OK | MB_ICONERROR); + return; + } + unsigned long insertnum; + if ((insertnum = curquad.references.addReference(newref)) == ERROR_SHRT) + { + MessageBox(refchild::hWnd, QUAD_REFID_EXISTS, L"Error", MB_OK | MB_ICONERROR); + return; + } + SQuad quad; + unsigned long listnum = (unsigned long)SendMessage(refchild::hWndRefList, LB_INSERTSTRING,(WPARAM)insertnum, (LPARAM)GenQuadReferenceItemString(newref,&quad).c_str()); + SendMessage(refchild::hWndRefList, LB_SETITEMDATA, (WPARAM)listnum,(LPARAM)quad.uniqueid); + SendMessage(refchild::hWndRefList, LB_SETCURSEL, (WPARAM)listnum, 0); + SetQuadSelectMode(false); + addingref = false; + EnableWindow(refchild::hWndRefList, true); + ChangeMade(); +} + +void ExportSection() +{ + std::wstring filename; + std::wstring filetitle; + SQuad tmpquad; + if (!dmmfile.getQuad(curquad.uniqueid, &tmpquad)) return; + std::wstringstream extensions; + std::wstring type = ConvertQuadToString(tmpquad.quadid.type); + extensions << type << L" Files (*." << type << L")|*." << type << L"|All Files (*.*)|*.*|"; + std::wstringstream newfiletitle; + std::wstring strplace; + if (tmpquad.string.getStringType() > STR_NONE) strplace = L" - " + tmpquad.string.getString(); + else strplace = L""; + newfiletitle << tmpquad.quadid.id << strplace << L"." << type; + if (!ShowSaveDlg(maindlg::hWnd, L"Export Section",extensions.str(),newfiletitle.str(),&filename, &filetitle)) return; + size_t lendata = curquad.section.getSectionDataSize(); + ////////////////////////////////// + ////// Prompt Decompression ////// + ////////////////////////////////// + + BYTE *sectiondatapointer = curquad.section.getSectionData(); + + bool decompress = false; + + if (curquad.section.isSectionCompressed()) + { + int retbox = MessageBox(maindlg::hWnd,L"This section is compressed, do you wish to export the decompressed version?", L"Section is Compressed", MB_YESNOCANCEL | MB_ICONQUESTION); + switch (retbox) + { + case IDCANCEL: + return; + break; + case IDNO: + decompress = false; + break; + case IDYES: + decompress = true; + break; + } + } + ////////////////////////////////// + ////////////////////////////////// + + if (decompress) + { + int uncompressedlength = GetSize(sectiondatapointer, lendata); + BYTE *uncompressed = new BYTE[uncompressedlength]; + DecompressSmart(sectiondatapointer, lendata, uncompressed); + sectiondatapointer = uncompressed; + lendata = uncompressedlength; + } + + FILE *fp = _wfopen(filename.c_str(), L"wb"); + if (fp == NULL) + { + MessageBox(maindlg::hWnd, L"Failed to open file for writing.", L"Error", MB_OK | MB_ICONEXCLAMATION); + return; + } + if (lendata == 0) + { + fclose(fp); + return; + } + if (fwrite(sectiondatapointer,sizeof(BYTE), lendata, fp) != lendata) + { + MessageBox(maindlg::hWnd, L"Error writing to file, written file may be corrupted.", L"Error", MB_OK | MB_ICONEXCLAMATION); + } + if (decompress) + { + delete [] sectiondatapointer; + } + fclose(fp); + return; +} + +void ImportSection() +{ + std::wstring filename; + std::wstring filetitle; + SQuad tmpquad; + if (!dmmfile.getQuad(curquad.uniqueid, &tmpquad)) return; + std::wstringstream extensions; + std::wstring type = ConvertQuadToString(tmpquad.quadid.type); + extensions << type << L" Files (*." << type << L")|*." << type << L"|All Files (*.*)|*.*|"; + if (!ShowOpenDlg(maindlg::hWnd, L"Import Section",extensions.str(),&filename, &filetitle)) return; + FILE *fp = _wfopen(filename.c_str(), L"rb"); + if (fp == NULL) + { + MessageBox(maindlg::hWnd, L"Failed to open file for reading.", L"Error", MB_OK | MB_ICONEXCLAMATION); + return; + } + unsigned long filesize = fsize(fp); + fseek(fp,SEEK_SET,0); + if (filesize == 0) + { + if (curSecDataIsNew && curquad.section.getSectionData() != NULL) delete [] curquad.section.getSectionData(); + curquad.section.setSectionData(NULL, 0); + curSecDataIsNew = false; + fclose(fp); + return; + } + + BYTE *newsection = new BYTE[filesize]; + fread(newsection, sizeof(BYTE), filesize, fp); + curquad.section.setSectionData(newsection,filesize); + fclose(fp); + curSecDataIsNew = true; + DisplaySectionInfo(); + ChangeMade(); +} + +void SetCurSection(BYTE* data, size_t size) +{ + if (curSecDataIsNew) + { + delete [] curquad.section.getSectionData(); + } + curquad.section.setSectionData(data, size); + curSecDataIsNew = true; +} \ No newline at end of file diff --git a/pencil++2/pclasserrors.h b/pencil++2/pclasserrors.h new file mode 100644 index 0000000..bfecd46 --- /dev/null +++ b/pencil++2/pclasserrors.h @@ -0,0 +1,20 @@ +/* 3DMM Pencil++ 2 + Copyright (C) 2005 Frankie Weindel */ + +//Errors +#define PERROR_NONE 0 +#define PERROR_FOPEN 1 +#define PERROR_NOTVALID 2 +#define PERROR_INVALIDQUADNUM 3 +#define PERROR_FOPENSAVE 4 +#define PERROR_ALREADYOPENED 5 +#define PERROR_NOFPATHEXISTS 6 + +//Error text +#define PERRORTXT_NONE L"No Error" +#define PERRORTXT_FOPEN L"Error opening the specifed file" +#define PERRORTXT_NOTVALID L"File not a valid 3DMM File" +#define PERRORTXT_INVALIDQUADNUM L"Quadnum specified not valid" +#define PERRORTXT_FOPENSAVE L"Error opening the specifed file for saving" +#define PERRORTXT_ALREADYOPENED L"Pencil class is already initialized. Close it and try again." +#define PERRORTXT_NOFPATHEXISTS L"No file path exists in pencil class. Use saveAs()." \ No newline at end of file diff --git a/pencil++2/pencil++2.vcxproj b/pencil++2/pencil++2.vcxproj new file mode 100644 index 0000000..6d6c8ac --- /dev/null +++ b/pencil++2/pencil++2.vcxproj @@ -0,0 +1,128 @@ + + + + + Debug + Win32 + + + Release + Win32 + + + + {09590B42-9C0E-4C79-B545-80A2F20F8D61} + Win32Proj + pencil2 + + + + Application + true + Unicode + + + Application + false + true + Unicode + + + + + + + + + + + + + true + + + false + + + + + + Level3 + Disabled + WIN32;_DEBUG;_WINDOWS;%(PreprocessorDefinitions) + + + Windows + true + DecompProxy.lib;comctl32.lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies) + + + + + Level3 + + + MaxSpeed + true + true + WIN32;NDEBUG;_WINDOWS;%(PreprocessorDefinitions) + + + Windows + true + true + true + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/pencil++2/pencil++2.vcxproj.filters b/pencil++2/pencil++2.vcxproj.filters new file mode 100644 index 0000000..c43170a --- /dev/null +++ b/pencil++2/pencil++2.vcxproj.filters @@ -0,0 +1,149 @@ + + + + + {4FC737F1-C7A5-4376-A066-2A32D752A2FF} + cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx + + + {93995380-89BD-4b04-88EB-625FBE52EBFB} + h;hpp;hxx;hm;inl;inc;xsd + + + {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} + rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms + + + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + + + Resource Files + + + \ No newline at end of file diff --git a/pencil++2/pencil.cpp b/pencil++2/pencil.cpp new file mode 100644 index 0000000..ebb7888 --- /dev/null +++ b/pencil++2/pencil.cpp @@ -0,0 +1,95 @@ +/* 3DMM Pencil++ 2 + Copyright (C) 2005 Frankie Weindel */ + +#include "pencil.h" + +HINSTANCE hInstance; + +CPencil dmmfile; +SQuad curquad; +std::wstring appPath; + +INT WINAPI WinMain(HINSTANCE hInst, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow) +{ + //Init Decomp DLL + char * c = new char[MAX_PATH]; + + + GetModuleFileNameA(NULL,c,(DWORD)MAX_PATH); + wchar_t *wc2 = new wchar_t[MAX_PATH]; + GetModuleFileName(NULL,wc2,(DWORD)MAX_PATH); + //MessageBox(NULL,c,c,MB_OK); + std::string appPath2; + appPath2 = c; + appPath = wc2; + //cout << appPath.substr(0,s.find_last_of("\\")+1) << endl; + appPath2 = appPath2.substr(0,appPath2.find_last_of("\\")+1); + appPath = appPath.substr(0,appPath.find_last_of(L"\\")+1); + delete[] wc2; + delete[] c; + if (!Init(((std::string)(appPath2 + "\\3DMOVIE.EXE")).c_str())) + { + MessageBox(NULL,L"3DMOVIE.EXE could not be found in your 3DMM Pencil++ 2 directory. Decompression functions will not work properly.",L"Error",MB_OK | MB_ICONEXCLAMATION); + } + /////////////////////////////////////////////////////////////////////////// + + LoadPlugins(); //load plugins (DUH!) + + INITCOMMONCONTROLSEX InitCtrlEx; + InitCtrlEx.dwSize = sizeof(INITCOMMONCONTROLSEX); + InitCtrlEx.dwICC = ICC_TAB_CLASSES | ICC_TREEVIEW_CLASSES; + InitCommonControlsEx(&InitCtrlEx); + + hInstance = hInst; + WNDCLASS wc; + if (!GetClassInfo(hInst,L"#32770",&wc)) + { + return 0; + } + + //wc.style = CS_HREDRAW | CS_VREDRAW | CS_OWNDC; // Redraw On Move, And Own DC For Window + //wc.lpfnWndProc = (WNDPROC) WndProc; // WndProc Handles Messages + //wc.cbClsExtra = 0; // No Extra Window Data + wc.cbWndExtra = DLGWINDOWEXTRA; // No Extra Window Data + + //wc.hInstance = hInst; // Set The Instance + wc.hIcon = LoadIcon(hInst, MAKEINTRESOURCE(IDI_ICON2)); // Load The Default Icon + //wc.hCursor = LoadCursor(NULL, IDC_ARROW); // Load The Arrow Pointer + //wc.hbrBackground = NULL; // No Background Required For GL + //wc.lpszMenuName = NULL; // We Don't Want A Menu + wc.lpszClassName = L"3DMMPencil"; // Set The Class Name + + + if (!RegisterClass(&wc)) // Attempt To Register The Window Class + { + MessageBox(NULL,L"Failed To Register The Window Class.",L"ERROR",MB_OK|MB_ICONEXCLAMATION); + return 1; // Exit And Return FALSE + } + dmmfile.createNew(); + int ret; + ret = (int)DialogBox(hInst, MAKEINTRESOURCE(IDD_DIALOG_MAIN), NULL ,(DLGPROC) MainDlgProc); + //ShowWindow(hwndGoto, nCmdShow); + // MSG msg; + + + //BOOL bRet; + + //while ( (bRet = GetMessage(&msg, NULL, 0, 0)) != 0 ) + //{ + // if (bRet == -1 ) + // { + // // handle the error and possibly exit + // } + // else if (!IsWindow(hwndGoto) || !IsDialogMessage(hwndGoto, &msg)) + // { + // TranslateMessage(&msg); + // DispatchMessage(&msg); + // } + //} + + UnregisterClass(L"3DMMPencil",hInst); + Shutdown(); + FreePlugins(); + return ret; + +} \ No newline at end of file diff --git a/pencil++2/pencil.h b/pencil++2/pencil.h new file mode 100644 index 0000000..8834d6c --- /dev/null +++ b/pencil++2/pencil.h @@ -0,0 +1,100 @@ +/* 3DMM Pencil++ 2 + Copyright (C) 2005 Frankie Weindel */ + +#ifndef _PENCIL_H +#define _PENCIL_H + + +#include +#include "resource.h" +#include "pencilclass.h" +#include +#include +#include "commctrl.h" +#include "dialogcontrols.h" +#include "globalconstants.h" +#include "usefulfuncs.h" +#include "decompproxy.h" +#include "plugins.h" +#include "editstructs.h" +extern HINSTANCE hInstance; + +extern CPencil dmmfile; +extern SQuad curquad; +extern std::wstring appPath; + +extern int currenttab; +extern bool tabrefloaded; +extern bool tabeditloaded; +extern bool tabhexloaded; + +extern bool treeviewloaded; + +extern bool quadselectmode; +extern bool addingref; +extern unsigned long lastcursel; + +extern SQuadID addquad; +extern bool curSecDataIsNew; + +//applychanges.cpp +extern bool changesMade; + + + +//maindialog.cpp +LRESULT CALLBACK MainDlgProc(HWND hWndDlg, UINT msg, WPARAM wParam, LPARAM lParam); +LRESULT CALLBACK WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam); +bool ProcessMainResize(short width, short height); +void SetStructureView(bool treeView); +void DoTreeView(); +void LoadTreeView(); +void SetTitle(std::wstring); + +//refdialog.cpp +LRESULT CALLBACK RefDlgProc(HWND hWndDlg, UINT msg, WPARAM wParam, LPARAM lParam); +void SetQuadSelectMode(bool mode); +void SelQuadQSM(); + +//viewhexdlg.cpp +LRESULT CALLBACK ViewHexDlgProc(HWND hWndDlg, UINT msg, WPARAM wParam, LPARAM lParam); +void SetViewHex(); + +//headerdlg.cpp +LRESULT CALLBACK EditHeaderDlgProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam); + +//quaddisplay.cpp +int ListQuads(); //Lists quads to the Quad List Box +int DisplayQuad(); //Gets current listbox selection and displays quad information in textboxes/etc. +void DisplayReferences(SQuadID quadid, CQuadReferences *references); //Handles reference tab data +void SetCurQuad(); //Sets curquad to the currently select quad +void DisplayReference(); //Displays currently selected reference data +void DisplaySectionInfo(); //Displays Section Length Info +void ChangeQuad(); //Automatically selects either quadselect mode select or setcurquad + +//applychanges.cpp +std::wstring GenQuadReferenceItemString(FF_3dmmIndexReference ref, SQuad *quad); //generates a string used in a reference list item +void ChangeReference(); //changes the currently selected reference with the data in the ref box +void ApplyChanges(); //applys quad changes +void ChangeMade(); //Called when a change is made to a quad.. enables Apply Changes button. +void ResetChangeMade(); //disables apply button, sets changes varible to false. +int PromptChangesMade(); //prompts changes made message box if changes are made. returns result. + +//modifyfilestructure.cpp +void AddReference(); +void RemoveReference(); +void AddQuad(); +void RemoveQuad(); +void MoveQuadUP(); +void MoveQuadDOWN(); +void ExportSection(); +void ImportSection(); +void SetCurSection(BYTE* data, size_t size); + +//finddlg.cpp +LRESULT CALLBACK FindDlgProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam); +void FindNext(); + + + +#endif \ No newline at end of file diff --git a/pencil++2/pencilbig.ico b/pencil++2/pencilbig.ico new file mode 100644 index 0000000..5f58e25 Binary files /dev/null and b/pencil++2/pencilbig.ico differ diff --git a/pencil++2/pencilclass.h b/pencil++2/pencilclass.h new file mode 100644 index 0000000..cced276 --- /dev/null +++ b/pencil++2/pencilclass.h @@ -0,0 +1,331 @@ +/* 3DMM Pencil++ 2 + Copyright (C) 2005 Frankie Weindel */ + +#ifndef _PENCILCLASS_H +#define _PENCILCLASS_H + +#include +#include +#include +#include +#include +#include "pclasserrors.h" +#include "fileformatstructs.h" +#include + +#define PENCIL_GOOD 0 +#define PENCIL_ERROR 1 + +//MagicNumbers +#define MN_1033 0x03030001 +#define MN_1055 0x05050001 + +#define ERROR_LNG 0xFFFFFFFF +#define ERROR_SHRT 0xFFFF +///////////////////////////////////////////// +//////Misc functions///////////////////////// +///////////////////////////////////////////// + +int CompareQuads(const char *sQuad1, const char *sQuad2); +int CompareQuads(quad qQuad1, const char *sQuad2); +int ConvertQuadToString(quad qQuad, char sQuad[5]); +int ConvertQuadToString(quad qQuad, wchar_t sQuad[5]); +std::wstring ConvertQuadToString(quad qQuad); +quad ConvertStringToQuad(const wchar_t sQuad[5]); +quad ConvertStringToQuad(const char sQuad[5]); +int ConvertWStrToStr(const wchar_t *wstr, char *str); +int ConvertStrToWStr(const char *str, wchar_t *wstr); +int _GetStringType(const wchar_t *wstr); +size_t FileSize(FILE *fp); +int fgoto(FILE *fp, long offset); +unsigned long fsize(FILE *fp); +quad GetQuadFromHWND(HWND hWnd); +int fixstring(char *string); + +struct SQuadID +{ + quad type; + unsigned long id; +}; + +struct SQuad; + + +class CQuadReferences +{ +public: + unsigned short addReference(FF_3dmmIndexReference reference); + unsigned short addReference(quad type, unsigned long id, unsigned long refid); //returns reference number, returns -1 on error (already the same reference) + std::vector getReferences() { return references; }; + bool getReference(unsigned short refnum, FF_3dmmIndexReference *retreference); + unsigned short getNumReferences() { return (unsigned short)references.size(); }; + bool removeReference(quad type, unsigned long refid); + bool removeReference(unsigned short refnum); + void clearReferences() { references.clear(); }; + bool checkReference(FF_3dmmIndexReference reference, FF_3dmmIndexReference ignore); + + unsigned short getNumOccurances(SQuadID quadid); + unsigned short getNumOccurances(quad type, unsigned long id); + std::vector *quads; + + void addCheck(FF_3dmmIndexReference reference); + std::vector checkRefs; +private: + std::vector references; + bool modifyTimesReferenced(quad type, unsigned long id, int value); +}; + +class CQuadSection +{ +public: + CQuadSection() { sectiondata = NULL; size = 0;}; + void setSectionData(BYTE *_sectiondata, size_t _size); + BYTE* getSectionData() {return sectiondata;}; + size_t getSectionDataSize() { return size; }; + size_t getUncompressedSectionDataSize(); + bool isSectionCompressed(); +private: + BYTE *sectiondata; + size_t size; + +}; + +#define STR_NONE 0 +#define STR_ASCII 1 +#define STR_UNICODE 2 + +#define STR_FORCE_AUTO 0 +#define STR_FORCE_ASCII 1 +#define STR_FORCE_UNICODE 2 + +class CQuadString +{ +public: + CQuadString(); + int setString(std::wstring _str); + int setString(std::string _str); + int getStringType() { return strtype; } + std::wstring getString(); + +private: + std::wstring str; + int strtype; + int force; +}; + +struct SRefBy +{ + SQuadID quadid; + long refid; + CQuadString string; + unsigned long uniqueid; +}; + +struct dmmEditHeader +{ + quad signature; + short unk1; + short unk2; + unsigned long magicnum; +}; + +struct SProcessData +{ + unsigned long quadoffset; + size_t quadsize; + unsigned long sectionoffset; + size_t sectionsize; +}; + +struct SQuad +{ + SQuadID quadid; + unsigned char mode; + + CQuadReferences references; + CQuadString string; + CQuadSection section; + + SProcessData temp; + + unsigned long uniqueid; + + unsigned short timesreferenced; +}; + +unsigned char GetQuadMode(SQuad* quad); + +#define GETQUAD_SECTIONORDERSORT 0 +#define GETQUAD_QUADORDERSORT 1 +#define GETQUAD_DIRSORT 2 + +class CQuadPointerSort +{ +public: + CQuadPointerSort(); + void addPointers(std::vector *quads); + void addPointer(SQuad* quad); + void removePointer(SQuad* quad); + void insertPointer(SQuad *quad, unsigned long where); + void setSortType(int _sorttype) { sorttype = _sorttype; }; + void clear() { quadpointers.clear(); }; + SQuad* getQuadPT(unsigned int quadnum); + unsigned long getItemNumber(SQuad* quad); + std::vector quadpointers; +private: + int sorttype; +}; + +#define FIND_ERR 0xFFFFFFFF +#define FIND_DOWN 0 +#define FIND_UP 1 +class CPencil +{ +public: + CPencil(); + ~CPencil(); + bool createNew(); + bool open(std::wstring path); + bool close(); + bool save(); + bool saveAs(std::wstring path, bool copy); + + int getLastError() { return lasterror; }; + std::wstring getLastErrorText(); + std::wstring getErrorText(int errnum); + dmmEditHeader header; + unsigned long getNumQuads() { return (unsigned long)quads.size(); }; + unsigned long getQuadNum(unsigned long uniqueid, int quadsort); + SQuad getQuad(unsigned long quadnum, int quadsort); + bool getQuad(unsigned long uniqueid, SQuad *retQuad); + bool getQuad(quad type, unsigned long id, SQuad *retQuad); + bool getQuad(SQuadID quadid, SQuad *retQuad); + bool getQuadRefBy(quad type, unsigned long id, std::vector *retRefBy); + bool getQuadRefBy(SQuadID quadid, std::vector *retRefBy); + + void doRefCheck(SQuad *quad, int value); + unsigned short getTimesReferenced(SQuadID quadid); + std::wstring getFPath() { return fpath; } + + unsigned long addQuad(SQuad *quad, unsigned long where); + bool removeQuad(unsigned long uniqueid); + bool changeQuad(SQuad *quad); + bool moveQuadUp(unsigned long uniqueid); + bool moveQuadDown(unsigned long uniqueid); + + bool checkQuadNumValidity(unsigned long quadnum); + + unsigned long findFromQuad_Type(quad type, unsigned long quadnumstart, int direction, int quadsort); + unsigned long findFromQuad_ID(unsigned long id, unsigned long quadnumstart, int direction, int quadsort); + unsigned long findFromQuad_QuadID(SQuadID quadid, unsigned long quadnumstart, int direction, int quadsort); + unsigned long findFromQuad_String(std::wstring str, unsigned long quadnumstart, int direction, int quadsort); +private: + bool fileIsOpen; + bool scan(); + void raiseError(int errnum); + + FILE *mainfp; //file pointer + + std::wstring fpath; //file path + + int lasterror; + + std::vector* getQuadPointerVector(int quadsort); + + std::vector quads; + CQuadPointerSort quadindexsort; + CQuadPointerSort directorysort; + + unsigned long lastuniqueid; + + SQuad* getQuadPT(SQuadID quadid); +}; + +//Sorts +class IndexAscendingQuadOffsetSort : public std::binary_function +{ +public: + bool operator()(const SQuad* rpStart, const SQuad* rpEnd) + { + return rpStart->temp.quadoffset < rpEnd->temp.quadoffset; + } +}; +class SectionOffsetSort : public std::binary_function +{ +public: + bool operator()(const SQuad* rpStart, const SQuad* rpEnd) + { + return rpStart->temp.sectionoffset < rpEnd->temp.sectionoffset; + } +}; +class SectionOffsetSortPT : public std::binary_function +{ +public: + bool operator()(const SQuad* rpStart, const SQuad* rpEnd) + { + return rpStart->temp.sectionoffset < rpEnd->temp.sectionoffset; + } +}; +class DirectorySort : public std::binary_function +{ +public: + bool operator()(const SQuad* rpStart, const SQuad* rpEnd) + { + if (rpStart->quadid.type == rpEnd->quadid.type) + { + return rpStart->quadid.id < rpEnd->quadid.id; + } + else + { + return rpStart->quadid.type < rpEnd->quadid.type; + } + } +}; + +//Finds + +struct FindQuadID: public std::unary_function +{ + SQuadID quadid; + bool operator()(const SQuad* obj) + { + return obj->quadid.id == quadid.id && obj->quadid.type == quadid.type; + } +}; +struct FindID: public std::unary_function +{ + unsigned long id; + bool operator()(const SQuad* obj) + { + return obj->quadid.id == id; + } +}; +struct FindQuad: public std::unary_function +{ + quad type; + bool operator()(const SQuad* obj) + { + return obj->quadid.type == type; + } +}; + +int wildcmp(wchar_t *wild,wchar_t *string); //Wildcard Comparer + +struct FindString: public std::unary_function +{ + std::wstring str; + bool operator()(SQuad* obj) + { + if (wildcmp((wchar_t*)str.c_str(),(wchar_t*)obj->string.getString().c_str())) + { + return 1; + } + else + { + return 0; + } + } +}; + + +#endif \ No newline at end of file diff --git a/pencil++2/pencilsmall.ico b/pencil++2/pencilsmall.ico new file mode 100644 index 0000000..a02c53d Binary files /dev/null and b/pencil++2/pencilsmall.ico differ diff --git a/pencil++2/plugins.cpp b/pencil++2/plugins.cpp new file mode 100644 index 0000000..3175b17 --- /dev/null +++ b/pencil++2/plugins.cpp @@ -0,0 +1,144 @@ +#include "plugins.h" + +std::vector plugins; +HWND hWndEditor; +SPlugin *curplugin; + +BYTE *uncompressedsectdata; +size_t uncompressedsectlen; +bool datadecomped = false; +void LoadPlugins() +{ + std::vector pluginfiles; + WIN32_FIND_DATA FindFileData; + HANDLE hFind; + //MessageBox(NULL,((string)appPath + "plugins\\*.dll").c_str(),"AFS",MB_OK); + hFind = FindFirstFile(((std::wstring)appPath + L"plugins\\*.dll").c_str(),&FindFileData); + if (hFind == INVALID_HANDLE_VALUE) + { + MessageBox(NULL,L"Plugin directory does not exist!",L"Error",MB_OK | MB_ICONERROR); + return; + } + else + { + pluginfiles.push_back(FindFileData.cFileName); + while (FindNextFile(hFind,&FindFileData)) + { + pluginfiles.push_back(FindFileData.cFileName); + } + //MessageBox(NULL,FindFileData.cFileName,"Error",MB_OK | MB_ICONERROR); + FindClose(hFind); + } + for (std::vector::iterator Iter = pluginfiles.begin(); Iter != pluginfiles.end(); Iter++) + { + SPlugin temp; + temp.hLib=LoadLibrary(((std::wstring)appPath + L"plugins\\" + (*Iter)).c_str()); + + if(temp.hLib==NULL) + { + MessageBox(NULL,((std::wstring)L"Unable to load plugin: " + (*Iter)).c_str(),L"Error",MB_OK | MB_ICONERROR); + continue; + } + typedef int (__cdecl*getfunc)(quad* quad); + typedef int (__cdecl*getbutton)(wchar_t button[20]); + typedef void (__cdecl*initplugin)(LRESULT (*sendpencilmessage) (UINT, LPARAM, WPARAM)); + //typedef int (__cdecl*setdatap)(char *p); + getbutton GetButtonName; + getfunc GetQuadTypes; + initplugin InitPlugin; + //setdatap SetDataPointer; + GetButtonName=(getbutton)GetProcAddress((HMODULE)temp.hLib,"GetButtonName"); + //SetDataPointer=(setdatap)GetProcAddress((HMODULE)temp.hLib, "SetDataPointer"); + GetQuadTypes=(getfunc)GetProcAddress((HMODULE)temp.hLib, "GetQuadTypes"); + InitPlugin=(initplugin)GetProcAddress((HMODULE)temp.hLib, "InitPlugin"); + temp.DisplayEditor=(cfunc)GetProcAddress((HMODULE)temp.hLib, "DisplayEditor"); + temp.DisplayAbout=(aboutfunc)GetProcAddress((HMODULE)temp.hLib, "DisplayAbout"); + temp.DisplayEditorEx=(cfuncEx)GetProcAddress((HMODULE)temp.hLib, "DisplayEditorEx"); + temp.CloseEditor=(closefunc)GetProcAddress((HMODULE)temp.hLib, "CloseEditor"); + temp.filetitle = (*Iter); + if((temp.DisplayEditor == NULL && temp.DisplayEditorEx == NULL) || GetQuadTypes == NULL || GetButtonName == NULL || InitPlugin == NULL || temp.DisplayAbout == NULL || temp.CloseEditor == NULL) + { + + MessageBox(NULL,((std::wstring)L"Unable to load fuction(s) in " + (*Iter)).c_str(),L"Error",MB_OK | MB_ICONERROR); + FreeLibrary((HMODULE)temp.hLib); + continue; + + } + + //char quad[255]; + + quad quadtype; + wchar_t button[20]={0}; + //SetDataPointer(quad); + //SetDataPointer(button); + InitPlugin(&SendPencilMessage); + while(GetQuadTypes(&quadtype)) + { + temp.QuadType.push_back(quadtype); + } + GetButtonName(button); + temp.button = button; + plugins.push_back(temp); + + } + return; + +} + +void FreePlugins() +{ + for (std::vector::iterator Iter = plugins.begin(); Iter != plugins.end(); Iter++) + { + FreeLibrary((HMODULE)Iter->hLib); + } +} + +void DisplayEditor() +{ + CloseEditor(); + SQuad quadd; + if (!dmmfile.getQuad(curquad.uniqueid, &quadd)) return; + for (std::vector::iterator itr = plugins.begin(); itr != plugins.end(); itr++) + { + for (std::vector::iterator qitr = itr->QuadType.begin(); qitr != itr->QuadType.end(); qitr++) + { + if ((*qitr) == quadd.quadid.type) + { + if (quadd.section.isSectionCompressed()) + { + datadecomped = true; + uncompressedsectlen = GetSize(quadd.section.getSectionData(), quadd.section.getSectionDataSize()); + uncompressedsectdata = new BYTE[uncompressedsectlen]; + DecompressSmart(quadd.section.getSectionData(), quadd.section.getSectionDataSize(), uncompressedsectdata); + } + else + { + datadecomped = false; + uncompressedsectdata = quadd.section.getSectionData(); + uncompressedsectlen = quadd.section.getSectionDataSize(); + } + curplugin = &(*itr); + hWndEditor = itr->DisplayEditor(maindlg::hWndTab, uncompressedsectdata, uncompressedsectlen); + RePosWindow(hWndEditor,5,23); + ShowWindow(hWndEditor,SW_SHOW); + } + } + } + tabeditloaded = true; + ProcessMainResize(0, 0); + +} + +void CloseEditor() +{ + if (curplugin == NULL) return; + curplugin->CloseEditor(); + curplugin = NULL; + hWndEditor = NULL; + if (datadecomped) + { + delete [] uncompressedsectdata; + datadecomped = false; + } + tabeditloaded = false; +} \ No newline at end of file diff --git a/pencil++2/plugins.h b/pencil++2/plugins.h new file mode 100644 index 0000000..f79f9a2 --- /dev/null +++ b/pencil++2/plugins.h @@ -0,0 +1,38 @@ +#ifndef _PLUGINS_H +#define _PLUGINS_H + +#include "pencil.h" +#include "externalmessaging.h" + +/////////////////////////// +//PLUGINS////////////////// +/////////////////////////// + + +typedef void (__cdecl*closefunc)(); +typedef HWND (__cdecl*cfunc)(HWND hWnd,BYTE *sectiondata, size_t sectionlen); +typedef int (__cdecl*aboutfunc)(HWND hWnd); +typedef int (__cdecl*cfuncEx)(HWND hWnd,BYTE *sectiondata, char quadtype[4], unsigned long id, const char *str); + + +struct SPlugin +{ + HINSTANCE hLib; + cfunc DisplayEditor; + cfuncEx DisplayEditorEx; + aboutfunc DisplayAbout; + closefunc CloseEditor; + std::vector QuadType; + std::wstring button; + std::wstring filetitle; +}; + +extern std::vector plugins; +extern HWND hWndEditor; + +void LoadPlugins(); +void FreePlugins(); +void DisplayEditor(); +void CloseEditor(); + +#endif \ No newline at end of file diff --git a/pencil++2/quaddisplay.cpp b/pencil++2/quaddisplay.cpp new file mode 100644 index 0000000..f03f184 --- /dev/null +++ b/pencil++2/quaddisplay.cpp @@ -0,0 +1,171 @@ +/* 3DMM Pencil++ 2 + Copyright (C) 2005 Frankie Weindel */ + +#include "pencil.h" + +int ListQuads() +{ + SendMessage(maindlg::hWndQuadList,WM_SETREDRAW,(WPARAM)FALSE,0); + SendMessage(maindlg::hWndQuadList, LB_RESETCONTENT, 0, 0); + unsigned long numquads = dmmfile.getNumQuads(); + for (unsigned long quadnum = 0; quadnum < numquads; quadnum++) + { + std::wstringstream ss; + SQuad curquad = dmmfile.getQuad(quadnum, GETQUAD_QUADORDERSORT); + if (curquad.string.getStringType() > STR_NONE) + { + ss << ConvertQuadToString(curquad.quadid.type) << L" - " << curquad.quadid.id << L" \"" << curquad.string.getString() << L"\""; + } + else + { + ss << ConvertQuadToString(curquad.quadid.type) << L" - " << curquad.quadid.id; + } + unsigned long listnum = (unsigned long)SendMessage(maindlg::hWndQuadList, LB_ADDSTRING, 0,(LPARAM) ss.str().c_str()); + SendMessage(maindlg::hWndQuadList, LB_SETITEMDATA, listnum,(LPARAM)curquad.uniqueid); + + } + SendMessage(maindlg::hWndQuadList,WM_SETREDRAW,(WPARAM)TRUE,0); + return 0; +} + + +void DisplayReferences(SQuadID quadid, CQuadReferences *references) +{ + SendMessage(refchild::hWndRefList,WM_SETREDRAW,(WPARAM)FALSE,0); + SendMessage(refchild::hWndRefList, LB_RESETCONTENT, 0, 0); + unsigned short numrefs = references->getNumReferences(); + for (int refnum = 0; refnum < numrefs; refnum++) + { + FF_3dmmIndexReference ref; + if (!references->getReference(refnum,&ref)) break; + SQuad quad; + unsigned long listnum = (unsigned long)SendMessage(refchild::hWndRefList, LB_ADDSTRING, 0, (LPARAM)GenQuadReferenceItemString(ref, &quad).c_str()); + SendMessage(refchild::hWndRefList, LB_SETITEMDATA, listnum,(LPARAM)quad.uniqueid); + } + SendMessage(refchild::hWndRefList,WM_SETREDRAW,(WPARAM)TRUE,0); + std::vector refby; + SendMessage(refchild::hWndRefByList, LB_RESETCONTENT, 0, 0); + if (dmmfile.getQuadRefBy(quadid, &refby)) + { + SendMessage(refchild::hWndRefByList,WM_SETREDRAW,(WPARAM)FALSE,0); + for (std::vector::iterator itr = refby.begin(); itr != refby.end(); itr++) + { + std::wstringstream ss; + if (itr->string.getStringType() > STR_NONE) + { + ss << ConvertQuadToString(itr->quadid.type) << L" - " << itr->quadid.id << L" : " << itr->refid << L" \"" << itr->string.getString() << L"\""; + } + else + { + ss << ConvertQuadToString(itr->quadid.type) << L" - " << itr->quadid.id << L" : " << itr->refid; + } + unsigned long listnum = (unsigned long)SendMessage(refchild::hWndRefByList, LB_ADDSTRING, 0, (LPARAM)ss.str().c_str()); + SendMessage(refchild::hWndRefByList, LB_SETITEMDATA, listnum,(LPARAM)itr->uniqueid); + } + SendMessage(refchild::hWndRefByList,WM_SETREDRAW,(WPARAM)TRUE,0); + } + tabrefloaded = true; +} + +void ChangeQuad() +{ + if (!quadselectmode) + { + SetCurQuad(); + DisplayQuad(); + } + else + { + SelQuadQSM(); + } +} + +void SetCurQuad() +{ + unsigned long cursel = (unsigned long)SendMessage(maindlg::hWndQuadList, LB_GETCURSEL, 0, 0); + + if (cursel == LB_ERR) return; + curquad = dmmfile.getQuad(cursel, GETQUAD_QUADORDERSORT); + if (curSecDataIsNew) + { + delete [] curquad.section.getSectionData(); + } + curSecDataIsNew = false; + lastcursel = cursel; +} + +int DisplayQuad() +{ + tabrefloaded = false; + tabeditloaded = false; + tabhexloaded = false; + + + SendMessage(maindlg::hWndQuadTxt, WM_SETTEXT, 0, (LPARAM)ConvertQuadToString(curquad.quadid.type).c_str()); + SendMessage(maindlg::hWndIDTxt, WM_SETTEXT, 0, (LPARAM)ConvertNumberToString(curquad.quadid.id).c_str()); + SendMessage(maindlg::hWndStrTxt, WM_SETTEXT, 0, (LPARAM)curquad.string.getString().c_str()); + DisplaySectionInfo(); + switch (currenttab) + { + case TAB_REFERENCES: + DisplayReferences(curquad.quadid,&curquad.references); + break; + case TAB_VIEWEDIT: + DisplayEditor(); + break; + case TAB_VIEWHEX: + SetViewHex(); + break; + } + ResetChangeMade(); + return 0; +} + +void DisplaySectionInfo() +{ + std::wstringstream lengthstring; + unsigned long sectiondatasize = curquad.section.getSectionDataSize(); + double megabytes = roundtodecimal(double(double(sectiondatasize) / 1048576), 2); + double kilobytes = roundtodecimal(double(double(sectiondatasize) / 1024), 2); + lengthstring << L"Length: "; + if (kilobytes >= 800.0) + { + lengthstring << megabytes << L" mb (" << sectiondatasize << L" bytes)"; + } + else + { + lengthstring << kilobytes << L" kb (" << sectiondatasize << L" bytes)"; + } + if (curquad.section.isSectionCompressed()) + { + size_t decomplen = curquad.section.getUncompressedSectionDataSize(); + lengthstring << std::endl << L"Compressed" << std::endl << L"Decomp Len: "; + megabytes = roundtodecimal(double(double(decomplen) / 1048576), 2); + kilobytes = roundtodecimal(double(double(decomplen) / 1024), 2); + if (kilobytes >= 800.0) + { + lengthstring << megabytes << L" mb (" << decomplen << L" bytes)"; + } + else + { + lengthstring << kilobytes << L" kb (" << decomplen << L" bytes)"; + } + } + else lengthstring << std::endl << L"Not Compressed"; + + SendMessage(maindlg::hWndOffLenLbl, WM_SETTEXT, 0,(LPARAM)lengthstring.str().c_str()); +} + +void DisplayReference() +{ + if (!quadselectmode) + { + unsigned long cursel = (unsigned long)SendMessage(refchild::hWndRefList, LB_GETCURSEL, 0,0); + if (cursel == LB_ERR) return; + FF_3dmmIndexReference reference; + curquad.references.getReference((unsigned short)cursel, &reference); + SendMessage(refchild::hWndQuadTxt, WM_SETTEXT, 0, (LPARAM)ConvertQuadToString(reference.type).c_str()); + SendMessage(refchild::hWndIDTxt, WM_SETTEXT, 0, (LPARAM)ConvertNumberToString(reference.id).c_str()); + SendMessage(refchild::hWndRefIDTxt, WM_SETTEXT, 0, (LPARAM)ConvertNumberToString(reference.refid).c_str()); + } +} \ No newline at end of file diff --git a/pencil++2/quads.cpp b/pencil++2/quads.cpp new file mode 100644 index 0000000..3df6d40 --- /dev/null +++ b/pencil++2/quads.cpp @@ -0,0 +1,187 @@ +/* 3DMM Pencil++ 2 + Copyright (C) 2005 Frankie Weindel */ + +#include "pencilclass.h" + +unsigned char GetQuadMode(SQuad* quad) +{ + if (CompareQuads(quad->quadid.type, "HTOP")) return 18; + if (quad->timesreferenced == 0) + { + if (quad->section.isSectionCompressed()) return 6; + else return 2; + } + else + { + if (quad->section.isSectionCompressed()) return 4; + else return 0; + } + return 0; +} + +bool CPencil::moveQuadUp(unsigned long uniqueid) +{ + + for (std::vector::iterator itr = quads.begin(); itr != quads.end(); itr++) + { + if ((*itr)->uniqueid == uniqueid) + { + unsigned long itemnum = quadindexsort.getItemNumber((*itr)); + if (itemnum == 0) + { + return false; + } + //std::wstringstream ss; + //ss << itemnum; + //MessageBox(NULL, ss.str().c_str(), L"EWFREW", MB_OK); + quadindexsort.removePointer((*itr)); + quadindexsort.insertPointer((*itr), itemnum - 1); + return true; + } + } + return false; +} + +bool CPencil::moveQuadDown(unsigned long uniqueid) +{ + for (std::vector::iterator itr = quads.begin(); itr != quads.end(); itr++) + { + if ((*itr)->uniqueid == uniqueid) + { + unsigned long itemnum = quadindexsort.getItemNumber((*itr)); + //std::wstringstream ss; + // ss << L"ITEMNUM: " << (unsigned long)itemnum; + //MessageBox (NULL, ss.str().c_str(), L"EWFREW", MB_OK); + if (itemnum >= quads.size() - 1) + { + + return false; + } + quadindexsort.removePointer((*itr)); + quadindexsort.insertPointer((*itr), itemnum + 1); + return true; + } + } + return false; +} + +unsigned short CPencil::getTimesReferenced(SQuadID quadid) +{ + unsigned short timesreferenced = 0; + for (std::vector::iterator iter = quads.begin(); iter != quads.end(); iter++) + { + timesreferenced += (*iter)->references.getNumOccurances(quadid); + } + return timesreferenced; +} + +SQuad* CPencil::getQuadPT(SQuadID quadid) +{ + for (std::vector::iterator itr = quads.begin(); itr != quads.end(); itr++) //Find Quad + { + if ((*itr)->quadid.type == quadid.type && (*itr)->quadid.id == quadid.id) + { + return (*itr); + } + } +} + +void CPencil::doRefCheck(SQuad *quad, int value) +{ + if (value == 0) + { + for (std::vector::iterator iter = quad->references.checkRefs.begin(); iter != quad->references.checkRefs.end(); iter++) + { + unsigned short timesreffed = getTimesReferenced((*iter)); + SQuad* thisquad = getQuadPT((*iter)); + if (thisquad) + { + thisquad->timesreferenced = timesreffed; + } + } + quad->references.checkRefs.clear(); + } + else if (value == 1) + { + unsigned short numrefs = quad->references.getNumReferences(); + for (unsigned short refnum = 0; refnum < numrefs; refnum++) + { + FF_3dmmIndexReference ref; + quad->references.getReference(refnum, &ref); + SQuadID quadid; + quadid.type = ref.type; + quadid.id = ref.id; + unsigned short timesreffed = getTimesReferenced(quadid); + SQuad* thisquad = getQuadPT(quadid); + if (thisquad) + { + thisquad->timesreferenced = timesreffed; + } + } + } + +} + +unsigned long CPencil::addQuad(SQuad *quad, unsigned long where) +{ + unsigned long newquadnum = (unsigned long)quads.size(); + if (where > newquadnum) return ERROR_LNG; //invalid where + if (getQuad(quad->quadid,NULL)) return ERROR_LNG; //already exists + quad->uniqueid = lastuniqueid++; + quad->references.quads = &quads; //pointer to quads struct + quad->timesreferenced = getTimesReferenced(quad->quadid); + doRefCheck(quad,1); + quads.push_back(quad); + quadindexsort.insertPointer(quads[newquadnum], where); + directorysort.addPointer(quads[newquadnum]); + + return quad->uniqueid; +} + +bool CPencil::removeQuad(unsigned long uniqueid) +{ + for (std::vector::iterator itr = quads.begin(); itr != quads.end(); itr++) + { + if ((*itr)->uniqueid == uniqueid) + { + + quadindexsort.removePointer((*itr)); + directorysort.removePointer((*itr)); + if ((*itr)->section.getSectionDataSize() > 0) + { + delete [] (*itr)->section.getSectionData(); + } + (*itr)->references.clearReferences(); + SQuad *quadptr = (*itr); + quads.erase (itr); + doRefCheck(quadptr,1); + delete quadptr; + return true; + } + } + return false; +} + +bool CPencil::changeQuad(SQuad *quad) +{ + SQuad foundquad; + if (getQuad(quad->quadid, &foundquad)) + { + if (foundquad.uniqueid != quad->uniqueid) return false; //if unique ids aren't the same then it's an already used quadid + } + + for (std::vector::iterator itr = quads.begin(); itr != quads.end(); itr++) + { + if ((*itr)->uniqueid == quad->uniqueid) + { + (*itr)->quadid = quad->quadid; + (*itr)->string = quad->string; + if ((*itr)->section.getSectionData() != (*quad).section.getSectionData()) delete [] (*itr)->section.getSectionData(); + (*itr)->section = quad->section; + (*itr)->references = quad->references; + doRefCheck((*itr), 0); + return true; + } + } + return false; //unique id not found +} \ No newline at end of file diff --git a/pencil++2/quadstring.cpp b/pencil++2/quadstring.cpp new file mode 100644 index 0000000..1086c63 --- /dev/null +++ b/pencil++2/quadstring.cpp @@ -0,0 +1,34 @@ +/* 3DMM Pencil++ 2 + Copyright (C) 2005 Frankie Weindel */ + +#include "pencilclass.h" + + +CQuadString::CQuadString() +{ + strtype = STR_NONE; +} + +int CQuadString::setString(std::wstring _str) +{ + strtype = _GetStringType(_str.c_str()); + str = _str; + return strtype; +} + +int CQuadString::setString(std::string _str) +{ + + int requiredchars = MultiByteToWideChar(CP_ACP, MB_PRECOMPOSED, _str.c_str(), -1, NULL, 0); + wchar_t *wstr = new wchar_t[requiredchars]; + MultiByteToWideChar(CP_ACP, MB_PRECOMPOSED, _str.c_str(), -1, wstr, requiredchars); + str = wstr; + strtype = _GetStringType(str.c_str()); + delete [] wstr; + return strtype; +} + +std::wstring CQuadString::getString() +{ + return str; +} \ No newline at end of file diff --git a/pencil++2/referencedialog.cpp b/pencil++2/referencedialog.cpp new file mode 100644 index 0000000..3891eb8 --- /dev/null +++ b/pencil++2/referencedialog.cpp @@ -0,0 +1,242 @@ +/* 3DMM Pencil++ 2 + Copyright (C) 2005 Frankie Weindel */ + +#include "pencil.h" + +bool quadselectmode = false; +bool addingref = false; + +namespace refchild +{ + HWND hWnd; + HWND hWndRefBox; + HWND hWndRefList; + HWND hWndQuadLbl; + HWND hWndIDLbl; + HWND hWndRefIDLbl; + HWND hWndQuadTxt; + HWND hWndIDTxt; + HWND hWndRefIDTxt; + HWND hWndAddBtn; + HWND hWndRemoveBtn; + HWND hWndQSelOKBtn; + HWND hWndChangeBtn; + HWND hWndRefByBox; + HWND hWndRefByList; +}; + +bool ProcessRefResize(short width, short height) +{ + RECT clientrect; + GetClientRect(refchild::hWnd, &clientrect); + short clientwidth = (short)clientrect.right; + short clientheight = (short)clientrect.bottom; + short boxheight = short(clientheight * 0.65); + + //if (listwidth > 425) { listwidth = 425; } + ResizeWindow(refchild::hWndRefBox, clientwidth - 5, boxheight); //Ref Box + short reflistheight = boxheight - 60; + ResizeWindow(refchild::hWndRefList, clientwidth - 50, reflistheight); //Ref List + short addrembuttonheight = reflistheight / 2; + ResizePosWindow(refchild::hWndAddBtn,clientwidth - 37, 14,28 , addrembuttonheight); + ResizePosWindow(refchild::hWndRemoveBtn,clientwidth - 37, 14 + addrembuttonheight + 2, 28 , addrembuttonheight); + short bottomreflisty = reflistheight + 18; + //Labels and text boxes + RePosWindow(refchild::hWndQuadLbl,10,bottomreflisty); + RePosWindow(refchild::hWndIDLbl,73,bottomreflisty); + RePosWindow(refchild::hWndRefIDLbl,169,bottomreflisty); + + RePosWindow(refchild::hWndQuadTxt,10,bottomreflisty + 15); + RePosWindow(refchild::hWndIDTxt,73,bottomreflisty + 15); + RePosWindow(refchild::hWndRefIDTxt,169,bottomreflisty + 15); + + RePosWindow(refchild::hWndChangeBtn,clientwidth - 72,bottomreflisty + 5); + RePosWindow(refchild::hWndQSelOKBtn,clientwidth - 140,bottomreflisty + 5); + + ResizePosWindow(refchild::hWndRefByBox, 2, boxheight, clientwidth - 5, clientheight - boxheight - 2); + ResizePosWindow(refchild::hWndRefByList, 10, boxheight + 15, clientwidth - 20, clientheight - boxheight - 23); + return true; +} + +LRESULT CALLBACK RefDlgProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam) +{ + switch(msg) + { + case WM_INITDIALOG: + refchild::hWnd = hWnd; + refchild::hWndRefBox = GetDlgItem(hWnd,IDC_REF_BOX); + refchild::hWndRefList = GetDlgItem(hWnd,IDC_LIST_REF); + refchild::hWndQuadLbl = GetDlgItem(hWnd,IDC_QUAD_LBL); + refchild::hWndIDLbl = GetDlgItem(hWnd,IDC_ID_LBL); + refchild::hWndRefIDLbl = GetDlgItem(hWnd,IDC_REFID_LBL); + refchild::hWndQuadTxt = GetDlgItem(hWnd,IDC_REFEDIT_QUADTYPE); + refchild::hWndIDTxt = GetDlgItem(hWnd,IDC_REFEDIT_ID); + refchild::hWndRefIDTxt = GetDlgItem(hWnd,IDC_REFEDIT_REFID); + refchild::hWndAddBtn = GetDlgItem(hWnd,IDC_REFEDIT_ADD); + refchild::hWndRemoveBtn = GetDlgItem(hWnd,IDC_REFEDIT_DELETE); + refchild::hWndChangeBtn = GetDlgItem(hWnd,IDC_REFEDIT_CHANGE); + refchild::hWndRefByBox = GetDlgItem(hWnd,IDC_REFBY_BOX); + refchild::hWndRefByList = GetDlgItem(hWnd,IDC_LIST_REFFEDBY); + refchild::hWndQSelOKBtn = GetDlgItem(hWnd, IDC_REFEDIT_OK); + return 1; + break; + case WM_QUIT: + case WM_CLOSE: + case WM_SIZE: + SetWindowLong(hWnd,DWL_MSGRESULT,ProcessRefResize(LOWORD(lParam), HIWORD(lParam))); + //MessageBox(hWnd, L"LOL", L"EFEW",MB_OK); + break; + case WM_ERASEBKGND: + return true; + break; + case WM_CTLCOLORSTATIC: + SetBkMode((HDC)wParam, TRANSPARENT); + return (LRESULT)(HBRUSH)GetStockObject(NULL_BRUSH); + break; + case WM_COMMAND: + switch(LOWORD(wParam)) + { + case IDC_LIST_REF: + switch (HIWORD(wParam)) + { + case LBN_SELCHANGE: + DisplayReference(); + break; + case LBN_DBLCLK: + if (!quadselectmode) + { + unsigned long cursel = (unsigned long)SendMessage(refchild::hWndRefList, LB_GETCURSEL, 0,0); + if (cursel != LB_ERR) + { + unsigned long uniqueid = (unsigned long)SendMessage(refchild::hWndRefList, LB_GETITEMDATA, cursel, 0); + unsigned long quadnum = dmmfile.getQuadNum(uniqueid, GETQUAD_QUADORDERSORT); + SendMessage(maindlg::hWndQuadList, LB_SETCURSEL, (WPARAM)quadnum, 0); + SetCurQuad(); + DisplayQuad(); + } + } + break; + } + break; + case IDC_LIST_REFFEDBY: + switch (HIWORD(wParam)) + { + case LBN_DBLCLK: + unsigned long cursel = (unsigned long)SendMessage(refchild::hWndRefByList, LB_GETCURSEL, 0,0); + if (cursel != LB_ERR) + { + unsigned long uniqueid = (unsigned long)SendMessage(refchild::hWndRefByList, LB_GETITEMDATA, cursel, 0); + unsigned long quadnum = dmmfile.getQuadNum(uniqueid, GETQUAD_QUADORDERSORT); + SendMessage(maindlg::hWndQuadList, LB_SETCURSEL, (WPARAM)quadnum, 0); + SetCurQuad(); + DisplayQuad(); + } + break; + } + break; + case IDC_REFEDIT_CHANGE: + if (quadselectmode) + { + SetQuadSelectMode(false); + addingref = false; + DisplayReference(); + EnableWindow(refchild::hWndRefList, true); + } + else + { + ChangeReference(); + } + break; + case IDC_REFEDIT_ADD: + EnableWindow(refchild::hWndRefList, false); + SetQuadSelectMode(true); + addingref = true; + break; + case IDC_REFEDIT_DELETE: + RemoveReference(); + break; + case IDC_REFEDIT_OK: + if (quadselectmode) + { + if (addingref) + { + AddReference(); + } + else + { + SetQuadSelectMode(false); + } + } + else SetQuadSelectMode(true); + break; + } + default:; + //MessageBox(hWnd, L"EWFGEW", L"EWFEW", MB_OK); + } + return 0; +} + +void SetQuadSelectMode(bool mode) +{ + switch (mode) + { + case true: + EnableWindow(maindlg::hWndAddQuadBtn, false); + EnableWindow(maindlg::hWndRemoveQuadBtn, false); + EnableWindow(maindlg::hWndMoveDownBtn, false); + EnableWindow(maindlg::hWndMoveUpBtn, false); + EnableWindow(maindlg::hWndQuadTxt, false); + EnableWindow(maindlg::hWndIDTxt, false); + EnableWindow(maindlg::hWndStrTxt, false); + + EnableWindow(maindlg::hWndQuadLbl, false); + EnableWindow(maindlg::hWndIDLbl, false); + EnableWindow(maindlg::hWndStrLbl, false); + EnableWindow(maindlg::hWndOffLenLbl, false); + + EnableWindow(maindlg::hWndExportBtn, false); + EnableWindow(maindlg::hWndImportBtn, false); + EnableWindow(maindlg::hWndApplyBtn, false); + EnableWindow(refchild::hWndAddBtn, false); + EnableWindow(refchild::hWndRemoveBtn, false); + EnableWindow(refchild::hWndRefByList, false); + + SendMessage(refchild::hWndQSelOKBtn, WM_SETTEXT, 0, (LPARAM)L"OK"); + SendMessage(refchild::hWndChangeBtn, WM_SETTEXT, 0, (LPARAM)L"Cancel"); + break; + case false: + EnableWindow(maindlg::hWndAddQuadBtn, true); + EnableWindow(maindlg::hWndRemoveQuadBtn, true); + EnableWindow(maindlg::hWndMoveDownBtn, true); + EnableWindow(maindlg::hWndMoveUpBtn, true); + EnableWindow(maindlg::hWndQuadTxt, true); + EnableWindow(maindlg::hWndIDTxt, true); + EnableWindow(maindlg::hWndStrTxt, true); + + EnableWindow(maindlg::hWndQuadLbl, true); + EnableWindow(maindlg::hWndIDLbl, true); + EnableWindow(maindlg::hWndStrLbl, true); + EnableWindow(maindlg::hWndOffLenLbl, true); + + EnableWindow(maindlg::hWndExportBtn, true); + EnableWindow(maindlg::hWndImportBtn, true); + EnableWindow(maindlg::hWndApplyBtn, true); + EnableWindow(refchild::hWndAddBtn, true); + EnableWindow(refchild::hWndRemoveBtn, true); + EnableWindow(refchild::hWndRefByList, true); + + SendMessage(refchild::hWndQSelOKBtn, WM_SETTEXT, 0, (LPARAM)L"Quad Sel"); + SendMessage(refchild::hWndChangeBtn, WM_SETTEXT, 0, (LPARAM)L"Change"); + SendMessage(maindlg::hWndQuadList, LB_SETCURSEL, lastcursel, 0); + break; + } + quadselectmode = mode; +} +void SelQuadQSM() +{ + unsigned long cursel = (unsigned long)SendMessage(maindlg::hWndQuadList, LB_GETCURSEL, 0, 0); + if (cursel == LB_ERR) return; + SQuad quad = dmmfile.getQuad(cursel,GETQUAD_QUADORDERSORT); + SendMessage(refchild::hWndQuadTxt, WM_SETTEXT, 0, (LPARAM)ConvertQuadToString(quad.quadid.type).c_str()); + SendMessage(refchild::hWndIDTxt, WM_SETTEXT, 0, (LPARAM)ConvertNumberToString(quad.quadid.id).c_str()); +} \ No newline at end of file diff --git a/pencil++2/references.cpp b/pencil++2/references.cpp new file mode 100644 index 0000000..09f054c --- /dev/null +++ b/pencil++2/references.cpp @@ -0,0 +1,170 @@ +/* 3DMM Pencil++ 2 + Copyright (C) 2005 Frankie Weindel */ + +#include "pencilclass.h" + +bool CQuadReferences::checkReference(FF_3dmmIndexReference reference, FF_3dmmIndexReference ignore) +{ + for (std::vector::iterator itr = references.begin(); itr != references.end(); itr++) + { + if (reference.type == itr->type && reference.refid == itr->refid) + { + if (reference.type == ignore.type && reference.refid == ignore.refid) continue; + else return false; + } + } + return true; +} +void CQuadReferences::addCheck(FF_3dmmIndexReference reference) +{ + SQuadID entry; + entry.type = reference.type; + entry.id = reference.id; + for (std::vector::iterator iter = checkRefs.begin(); iter != checkRefs.end(); iter++) + { + if ((*iter).type == entry.type && (*iter).id == entry.id) return; + } + checkRefs.push_back(entry); +} +bool CQuadReferences::modifyTimesReferenced(quad type, unsigned long id, int value) +{ + for (std::vector::iterator iter = quads->begin(); iter != quads->end(); iter++) + { + if ((*iter)->quadid.type == type && (*iter)->quadid.id == id) + { + (*(*iter)).timesreferenced += value; + return true; + } + } + return false; +} + +unsigned short CQuadReferences::addReference(FF_3dmmIndexReference reference) +{ + unsigned short retVal; + if (references.size() == 0) //If there are no other references in the std::vector then just add it + { + references.push_back(reference); + addCheck(reference); + return (int)references.size() - 1; + } + else + { + for (std::vector::iterator itr = references.begin(); itr != references.end(); itr++) + { + + if (reference.refid < itr->refid) + { + if ((unsigned short)(itr - references.begin()) == 0) + { + retVal = (unsigned short)(itr - references.begin()); + references.insert(itr,reference); + addCheck(reference); + return retVal; + } + std::vector::iterator prevItr = itr - 1; + if (reference.refid > prevItr->refid) + { + retVal = (unsigned short)(itr - references.begin()); + references.insert(itr,reference); + addCheck(reference); + return retVal; + } + else if (reference.refid == prevItr->refid) + { + + if (reference.type > prevItr->type) //Type is greater than prev type, we can add it + { + retVal = (unsigned short)(itr - references.begin()); + references.insert(itr,reference); + addCheck(reference); + return retVal; + } + else if (reference.type == prevItr->type) //Type and ref ids are the same?? Can't add it at all.. + { + return ERROR_SHRT; + } + } + } + else if (reference.refid == itr->refid) + { + if (reference.type < itr->type) + { + retVal = (unsigned short)(itr - references.begin()); + references.insert(itr,reference); + addCheck(reference); + return retVal; + } + else if (reference.type == itr->type) + { + return ERROR_SHRT; + } + } + std::vector::iterator nextItr = itr + 1; + if (nextItr == references.end()) //If our next iterator is the end then just add it to the end + { + //MessageBox(NULL,L"SDFSD",L"SDFDSF",MB_OK); + references.push_back(reference); + addCheck(reference); + return int(references.size() - 1); + } + + } + } + return ERROR_SHRT; +} + +unsigned short CQuadReferences::addReference(quad type, unsigned long id, unsigned long refid) +{ + FF_3dmmIndexReference ref; + ref.type = type; + ref.id = id; + ref.refid = refid; + return addReference(ref); +} + +bool CQuadReferences::removeReference(quad type, unsigned long refid) +{ + for (std::vector::iterator itr = references.begin(); itr != references.end(); itr++) + { + if (itr->type == type && itr->refid == refid) + { + addCheck((*itr)); + references.erase(itr); + return true; + } + } + return false; +} + +bool CQuadReferences::removeReference(unsigned short refnum) +{ + if (refnum < 0 || (unsigned)refnum >= references.size()) return false; + addCheck(references[refnum]); + references.erase(references.begin() + refnum); + return true; +} + +bool CQuadReferences::getReference(unsigned short refnum, FF_3dmmIndexReference *retreference) +{ + if (refnum < 0 || (unsigned)refnum >= references.size()) return false; + retreference->type = references[refnum].type; + retreference->id = references[refnum].id; + retreference->refid = references[refnum].refid; + return true; +} + +unsigned short CQuadReferences::getNumOccurances(SQuadID quadid) +{ + return getNumOccurances(quadid.type, quadid.id); +} + +unsigned short CQuadReferences::getNumOccurances(quad type, unsigned long id) +{ + unsigned short occurances = 0; + for (std::vector::iterator itr = references.begin(); itr != references.end(); itr++) + { + if (itr->type == type && itr->id == id) occurances++; + } + return occurances; +} \ No newline at end of file diff --git a/pencil++2/resource.h b/pencil++2/resource.h new file mode 100644 index 0000000..f3f4830 --- /dev/null +++ b/pencil++2/resource.h @@ -0,0 +1,120 @@ +//{{NO_DEPENDENCIES}} +// Microsoft Visual C++ generated include file. +// Used by resource.rc +// +#define IDD_DIALOG_MAIN 101 +#define IDD_DIALOG_ADDQUAD 104 +#define IDD_DIALOG_ADDREF 105 +#define IDR_MAIN_MENU 106 +#define ID_FILE_EXIT 107 +#define IDD_DIALOG1 109 +#define IDD_FIND 109 +#define ID_FILE_OPEN110 110 +#define ID_FILE_SAVEAS1 111 +#define ID_FILE_SAVEAS 112 +#define ID_FILE_SAVEAS113 113 +#define ID_FILE_EXIT114 114 +#define IDD_HEADER 115 +#define ID_HEADERINFO 116 +#define ID_MENU_HEADER 116 +#define ID_MENUED 116 +#define ID_Menu 117 +#define ID_EDIT_FIND1 119 +#define IDD_TREEVIEW 120 +#define ID_EDIT_TREEVIEW 121 +#define IDD_DIALOG2 122 +#define IDD_VIEWHEX 122 +#define IDI_ICON1 123 +#define IDD_DIALOG_ABOUT 125 +#define ID_HELP126 126 +#define ID_HELP_ABOUT 127 +#define IDR_MENU1 128 +#define ID_FEF_FEF 130 +#define IDI_ICON2 131 +#define IDD_REFERENCES 132 +#define IDD_VIEW_HEX 133 +#define IDC_QUAD_LIST 1002 +#define IDC_SECTION_ADD 1006 +#define IDC_SECTION_MVDN 1007 +#define IDC_SECTIONEDIT_QUADTYPE 1008 +#define IDC_SECTION_DELETE 1009 +#define IDC_SECTION_MVUP 1010 +#define IDC_SECTIONEDIT_ID 1011 +#define IDC_INF_SECT_DATA 1012 +#define IDC_SECT_VIEWHEX 1013 +#define IDC_LOC_SECT_DATA 1014 +#define IDC_SECT_IMPORT 1015 +#define IDC_SECT_EDIT 1016 +#define IDC_SECT_EXPORT 1017 +#define IDC_LOC_SECT_DATA2 1018 +#define IDC_APPLY_C 1019 +#define IDC_APPLY_CHANGE 1019 +#define IDC_COMBO_MODE 1020 +#define IDC_SECTIONEDIT_STRING 1021 +#define IDC_EDIT_OTHER_MODE 1022 +#define IDC_BUT_DETECT 1023 +#define IDC_LIST_REF 1024 +#define IDC_REFEDIT_MVUP 1025 +#define IDC_REFEDIT_MVDN 1026 +#define IDC_REFEDIT_ADD 1027 +#define IDC_REFEDIT_DELETE 1028 +#define IDC_REFEDIT_CHANGE 1029 +#define IDC_LIST_REFFEDBY 1030 +#define IDC_REFEDIT_QUADTYPE 1031 +#define IDC_REFEDIT_ID 1032 +#define IDC_QUADTYPE 1033 +#define IDC_REFEDIT_REFID 1033 +#define IDC_QUADID 1034 +#define IDC_REFEDIT_OK 1034 +#define IDC_FIND_FINDNEXT 1036 +#define IDC_FINDNEXT 1036 +#define IDC_FIND_TYPE 1038 +#define IDC_FIND_ID 1039 +#define IDC_FIND_STR 1040 +#define IDC_FORCEUNICODE 1040 +#define IDC_UNK2 1040 +#define IDC_TIMESREFFED 1042 +#define IDC_MAGICNUM 1044 +#define IDC_UNK1 1045 +#define IDC_LIST1 1046 +#define IDC_LIST_PLUGINS 1046 +#define IDC_EDIT_HEIGHT 1047 +#define IDC_EDIT_WIDTH 1048 +#define IDC_EDIT2 1049 +#define IDC_EDIT_VIEWHEX 1049 +#define IDC_BUTTON1 1050 +#define IDC_EDIT_CHANGE 1050 +#define IDC_SEARCHBY_QUADID 1051 +#define IDC_SEARCHBY_STRING 1052 +#define IDC_DIRECT_UP 1053 +#define IDC_DIRECT_DOWN 1054 +#define IDC_TREEVIEW 1055 +#define IDC_HOTKEY1 1057 +#define IDC_ABOUTPLUGIN 1058 +#define IDC_TAB2 1061 +#define IDC_TAB1 1063 +#define IDC_SECTBOX 1064 +#define IDC_QUAD_LBL 1065 +#define IDC_ID_LBL 1066 +#define IDC_STRING_LBL 1067 +#define IDC_REF_BOX 1068 +#define IDC_REFBY_BOX 1069 +#define IDC_REFID_LBL 1070 +#define IDC_EDIT1 1072 +#define IDC_STRTYPE 1075 +#define IDC_SIGNATURE 1076 +#define ID_FILE_NEW1 57600 +#define ID 57600 +#define ID_FILE_OPEN1 57601 +#define ID_FILE_SAVE1 57603 + +// Next default values for new objects +// +#ifdef APSTUDIO_INVOKED +#ifndef APSTUDIO_READONLY_SYMBOLS +#define _APS_NEXT_RESOURCE_VALUE 134 +#define _APS_NEXT_COMMAND_VALUE 40001 +#define _APS_NEXT_CONTROL_VALUE 1078 +#define _APS_NEXT_SYMED_VALUE 101 +#endif +#endif diff --git a/pencil++2/resource.rc b/pencil++2/resource.rc new file mode 100644 index 0000000..e9acbd6 --- /dev/null +++ b/pencil++2/resource.rc @@ -0,0 +1,279 @@ +// Microsoft Visual C++ generated resource script. +// +#include "resource.h" + +#define APSTUDIO_READONLY_SYMBOLS +///////////////////////////////////////////////////////////////////////////// +// +// Generated from the TEXTINCLUDE 2 resource. +// +#include "windows.h" +#define IDC_STATIC -1 + +///////////////////////////////////////////////////////////////////////////// +#undef APSTUDIO_READONLY_SYMBOLS + +///////////////////////////////////////////////////////////////////////////// +// English (U.S.) resources + +#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU) +#ifdef _WIN32 +LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US +#pragma code_page(1252) +#endif //_WIN32 + +#ifdef APSTUDIO_INVOKED +///////////////////////////////////////////////////////////////////////////// +// +// TEXTINCLUDE +// + +1 TEXTINCLUDE +BEGIN + "resource.h\0" +END + +2 TEXTINCLUDE +BEGIN + "#include ""afxres.h""\r\n" + "\0" +END + +3 TEXTINCLUDE +BEGIN + "\r\n" + "\0" +END + +#endif // APSTUDIO_INVOKED + + +///////////////////////////////////////////////////////////////////////////// +// +// Dialog +// + +IDD_DIALOG_MAIN DIALOGEX 0, 0, 561, 372 +STYLE DS_SETFONT | DS_FIXEDSYS | DS_CENTER | DS_CENTERMOUSE | WS_MINIMIZEBOX | + WS_MAXIMIZEBOX | WS_VISIBLE | WS_CAPTION | WS_SYSMENU | WS_THICKFRAME +EXSTYLE WS_EX_APPWINDOW +CAPTION "3DMM Pencil++ 2 Beta 1" +MENU IDR_MAIN_MENU +CLASS "3DMMPencil" +FONT 8, "MS Shell Dlg", 400, 0, 0x1 +BEGIN + LISTBOX IDC_QUAD_LIST,6,5,114,331,LBS_NOINTEGRALHEIGHT | + WS_VSCROLL | WS_TABSTOP + PUSHBUTTON "+",IDC_SECTION_ADD,66,343,54,24 + PUSHBUTTON "-",IDC_SECTION_DELETE,126,343,54,24 + PUSHBUTTON "Move Down",IDC_SECTION_MVDN,186,343,54,24 + PUSHBUTTON "Move Up",IDC_SECTION_MVUP,6,343,54,24 + EDITTEXT IDC_SECTIONEDIT_QUADTYPE,246,18,37,12,ES_UPPERCASE | + ES_AUTOHSCROLL + EDITTEXT IDC_SECTIONEDIT_ID,246,42,60,12,ES_AUTOHSCROLL | + ES_NUMBER + GROUPBOX "Section Data",IDC_SECTBOX,246,324,264,42 + CONTROL "Offset:\nLength:",IDC_INF_SECT_DATA,"Static", + SS_LEFTNOWORDWRAP | WS_GROUP,252,334,136,27 + PUSHBUTTON "Import...",IDC_SECT_IMPORT,391,333,53,28 + PUSHBUTTON "Export...",IDC_SECT_EXPORT,448,333,56,28 + PUSHBUTTON "Apply Changes",IDC_APPLY_CHANGE,512,327,41,39, + BS_MULTILINE + LTEXT "Quad:",IDC_QUAD_LBL,246,8,48,8 + LTEXT "ID:",IDC_ID_LBL,246,32,48,8 + LTEXT "String:",IDC_STRING_LBL,246,56,48,8 + EDITTEXT IDC_SECTIONEDIT_STRING,246,66,180,12,ES_AUTOHSCROLL + CONTROL "",IDC_TAB1,"SysTabControl32",0x0,246,84,312,234 + CONTROL "",IDC_TREEVIEW,"SysTreeView32",TVS_HASBUTTONS | + TVS_HASLINES | TVS_LINESATROOT | WS_BORDER | WS_TABSTOP, + 120,6,120,330 +END + +IDD_HEADER DIALOGEX 0, 0, 154, 114 +STYLE DS_SETFONT | DS_MODALFRAME | DS_FIXEDSYS | DS_CENTER | WS_POPUP | + WS_CAPTION | WS_SYSMENU +CAPTION "Header Information" +FONT 8, "MS Shell Dlg", 400, 0, 0x1 +BEGIN + DEFPUSHBUTTON "OK",IDOK,7,95,63,14 + PUSHBUTTON "Cancel",IDCANCEL,83,95,63,14 + EDITTEXT IDC_SIGNATURE,57,17,37,12,ES_UPPERCASE | ES_AUTOHSCROLL + LTEXT "Signature:",IDC_STATIC,20,18,32,12 + EDITTEXT IDC_UNK1,57,34,37,12,ES_AUTOHSCROLL | ES_NUMBER + LTEXT "UNK1:",IDC_STATIC,32,34,22,12 + EDITTEXT IDC_UNK2,57,51,37,12,ES_AUTOHSCROLL | ES_NUMBER + LTEXT "UNK2:",IDC_STATIC,31,50,22,12 + COMBOBOX IDC_STRTYPE,57,67,92,41,CBS_DROPDOWNLIST | CBS_SORT | + WS_VSCROLL | WS_TABSTOP + LTEXT "String Type:",IDC_STATIC,11,69,41,12 +END + +IDD_REFERENCES DIALOGEX 0, 0, 302, 218 +STYLE DS_SETFONT | DS_FIXEDSYS | WS_CHILD | WS_SYSMENU +EXSTYLE WS_EX_TRANSPARENT +FONT 8, "MS Shell Dlg", 400, 0, 0x1 +BEGIN + GROUPBOX "References",IDC_REF_BOX,1,0,300,150 + LISTBOX IDC_LIST_REF,6,9,264,111,LBS_NOINTEGRALHEIGHT | + WS_VSCROLL | WS_TABSTOP + PUSHBUTTON "+",IDC_REFEDIT_ADD,276,6,20,57 + PUSHBUTTON "-",IDC_REFEDIT_DELETE,276,66,20,54 + PUSHBUTTON "Change",IDC_REFEDIT_CHANGE,252,123,42,17 + GROUPBOX "Referenced By",IDC_REFBY_BOX,0,153,300,62 + LISTBOX IDC_LIST_REFFEDBY,6,162,288,47,LBS_NOINTEGRALHEIGHT | + WS_VSCROLL | WS_TABSTOP + EDITTEXT IDC_REFEDIT_QUADTYPE,6,130,37,12,ES_UPPERCASE | + ES_AUTOHSCROLL + LTEXT "Quad:",IDC_QUAD_LBL,6,120,39,8 + EDITTEXT IDC_REFEDIT_ID,48,130,60,12,ES_AUTOHSCROLL | ES_NUMBER + LTEXT "ID:",IDC_ID_LBL,50,120,48,8 + EDITTEXT IDC_REFEDIT_REFID,112,130,60,12,ES_AUTOHSCROLL | + ES_NUMBER + LTEXT "Ref ID:",IDC_REFID_LBL,114,120,48,8 + PUSHBUTTON "Quad Select",IDC_REFEDIT_OK,202,123,43,17 +END + +IDD_VIEW_HEX DIALOGEX 0, 0, 294, 194 +STYLE DS_SETFONT | DS_FIXEDSYS | DS_CONTROL | WS_CHILD | WS_SYSMENU +EXSTYLE WS_EX_TRANSPARENT +FONT 8, "MS Shell Dlg", 400, 0, 0x1 +BEGIN + EDITTEXT IDC_EDIT1,9,9,256,169,ES_MULTILINE | ES_AUTOVSCROLL | + ES_AUTOHSCROLL | WS_VSCROLL | WS_HSCROLL +END + +IDD_DIALOG_ADDQUAD DIALOGEX 0, 0, 118, 54 +STYLE DS_SETFONT | DS_MODALFRAME | DS_FIXEDSYS | DS_CENTER | WS_POPUP | + WS_CAPTION | WS_SYSMENU +CAPTION "Insert New Quad" +FONT 8, "MS Shell Dlg", 400, 0, 0x1 +BEGIN + DEFPUSHBUTTON "OK",IDOK,7,33,50,14 + PUSHBUTTON "Cancel",IDCANCEL,61,33,50,14 + EDITTEXT IDC_QUADTYPE,8,12,37,12,ES_UPPERCASE | ES_AUTOHSCROLL + EDITTEXT IDC_QUADID,50,12,61,12,ES_AUTOHSCROLL | ES_NUMBER + LTEXT "Quad:",IDC_STATIC,9,3,30,8 + LTEXT "ID:",IDC_STATIC,51,3,24,8 +END + +IDD_FIND DIALOGEX 0, 0, 311, 83 +STYLE DS_SETFONT | DS_MODALFRAME | DS_FIXEDSYS | DS_CENTER | WS_POPUP | + WS_CAPTION | WS_SYSMENU +EXSTYLE WS_EX_WINDOWEDGE +CAPTION "Find" +FONT 8, "MS Shell Dlg", 400, 0, 0x1 +BEGIN + DEFPUSHBUTTON "Find Next",IDC_FINDNEXT,254,10,50,14 + PUSHBUTTON "Cancel",IDCANCEL,254,30,50,14 + EDITTEXT IDC_FIND_TYPE,16,21,37,12,ES_UPPERCASE | ES_AUTOHSCROLL + EDITTEXT IDC_FIND_ID,58,21,61,12,ES_AUTOHSCROLL | ES_NUMBER + LTEXT "Quad:",IDC_STATIC,17,11,30,8 + LTEXT "ID:",IDC_STATIC,59,11,24,8 + EDITTEXT IDC_FIND_STR,126,21,113,12,ES_AUTOHSCROLL + LTEXT "String:",IDC_STATIC,127,11,24,8 + LTEXT "Search By:",IDC_STATIC,15,37,38,8 + CONTROL "Quad and/or ID",IDC_SEARCHBY_QUADID,"Button", + BS_AUTORADIOBUTTON | WS_GROUP,55,36,64,11 + CONTROL "String",IDC_SEARCHBY_STRING,"Button",BS_AUTORADIOBUTTON, + 122,36,38,11 + GROUPBOX "Direction",IDC_STATIC,160,37,79,37 + CONTROL "Up",IDC_DIRECT_UP,"Button",BS_AUTORADIOBUTTON | + WS_GROUP,166,47,49,9 + CONTROL "Down",IDC_DIRECT_DOWN,"Button",BS_AUTORADIOBUTTON,166, + 58,44,11 +END + + +///////////////////////////////////////////////////////////////////////////// +// +// Menu +// + +IDR_MAIN_MENU MENUEX +BEGIN + POPUP "&File", 65535,MFT_STRING,MFS_ENABLED + BEGIN + MENUITEM "&New", 57600,MFT_STRING,MFS_ENABLED + MENUITEM "&Open...", 57601,MFT_STRING,MFS_ENABLED + MENUITEM "&Save", 57603,MFT_STRING,MFS_ENABLED + MENUITEM "Save &As...", 111,MFT_STRING,MFS_ENABLED + MENUITEM MFT_SEPARATOR + MENUITEM "&Exit", 107,MFT_STRING,MFS_ENABLED + END + POPUP "&Edit", 65535,MFT_STRING,MFS_ENABLED + BEGIN + MENUITEM "&Find", 119,MFT_STRING,MFS_ENABLED + MENUITEM "Tree &View", 121,MFT_STRING,MFS_ENABLED + END + MENUITEM "&Header Info", 116,MFT_STRING,MFS_ENABLED + POPUP "Help", 65535, + MFT_STRING | MFT_RIGHTJUSTIFY,MFS_ENABLED + BEGIN + MENUITEM "About...", 127,MFT_STRING,MFS_ENABLED + END +END + +///////////////////////////////////////////////////////////////////////////// +// +// Icon +// + +// Icon with lowest ID value placed first to ensure application icon +// remains consistent on all systems. +IDI_ICON2 ICON "ico.ico" + +///////////////////////////////////////////////////////////////////////////// +// +// Version +// + +VS_VERSION_INFO VERSIONINFO + FILEVERSION 0,0,1,2 + PRODUCTVERSION 0,0,1,2 + FILEFLAGSMASK 0x37L +#ifdef _DEBUG + FILEFLAGS 0x21L +#else + FILEFLAGS 0x20L +#endif + FILEOS 0x4L + FILETYPE 0x1L + FILESUBTYPE 0x0L +BEGIN + BLOCK "StringFileInfo" + BEGIN + BLOCK "040904b0" + BEGIN + VALUE "Comments", "Uh oh!" + VALUE "CompanyName", "Frankie Weindel" + VALUE "FileDescription", "3DMM Pencil++ 2" + VALUE "FileVersion", "0, 0, 1, 2" + VALUE "InternalName", "3dmmpenc" + VALUE "LegalCopyright", "Copyright (C) 2005 Frankie Weindel" + VALUE "OriginalFilename", "3dmmpenc.exe" + VALUE "ProductName", " 3dmmpenc Application" + VALUE "ProductVersion", "0, 0, 1, 2" + VALUE "SpecialBuild", "The Beginning" + END + END + BLOCK "VarFileInfo" + BEGIN + VALUE "Translation", 0x409, 1200 + END +END + +#endif // English (U.S.) resources +///////////////////////////////////////////////////////////////////////////// + + + +#ifndef APSTUDIO_INVOKED +///////////////////////////////////////////////////////////////////////////// +// +// Generated from the TEXTINCLUDE 3 resource. +// + + +///////////////////////////////////////////////////////////////////////////// +#endif // not APSTUDIO_INVOKED + diff --git a/pencil++2/saver.cpp b/pencil++2/saver.cpp new file mode 100644 index 0000000..fdb2961 --- /dev/null +++ b/pencil++2/saver.cpp @@ -0,0 +1,164 @@ +/* 3DMM Pencil++ 2 + Copyright (C) 2005 Frankie Weindel */ + +#include "pencilclass.h" + +bool CPencil::save() +{ + if (fpath == L"") + { + raiseError(PERROR_NOFPATHEXISTS); + return false; + } + else + { + saveAs(fpath, false); + } +} + +bool CPencil::saveAs(std::wstring path, bool copy) +{ + FILE *mainfp = _wfopen(path.c_str(), L"wb"); + if (!mainfp) + { + raiseError(PERROR_FOPENSAVE); + return false; + } + FF_3dmmHeader head; + head.identifier = ConvertStringToQuad("2NHC"); //our main man! + head.magicnum = header.magicnum; + head.signature = header.signature; + head.unk1 = header.unk1; + head.unk2 = header.unk2; + memset(head.zeros,0,96); //set zeros to 0 + //allocate room for header by skipping it + fseek(mainfp,sizeof(FF_3dmmHeader), SEEK_CUR); + //Write each section and store its location + for (std::vector::iterator itr = quads.begin(); itr != quads.end(); itr++) + { + SQuad *quadptr = (*itr); + BYTE* data = quadptr->section.getSectionData(); + size_t datalen = quadptr->section.getSectionDataSize(); + quadptr->temp.sectionoffset = ftell(mainfp); + quadptr->temp.sectionsize = datalen; + fwrite(data, sizeof(BYTE), datalen, mainfp); + } + //Prepare Index Header Data, but do not write until we finish writing the index + FF_3dmmIndexHeader indexhead; + indexhead.magicnum = head.magicnum; + indexhead.numsections = quads.size(); + indexhead.unk20 = 20; + indexhead.FFFFFFFF = 0xFFFFFFFF; + //we must set indexhead.quadindexlen after we know how long it is then we write this struct to the file + head.indexoffset = ftell(mainfp); //set header index offset; + + head.indexlen = sizeof(FF_3dmmIndexHeader); //start lencount at the size of the header + //Skip over and allocate room for the index header + fseek(mainfp, sizeof(FF_3dmmIndexHeader), SEEK_CUR); + + //WRITE INDEX!!!! + indexhead.quadindexlen = 0; + for (std::vector::iterator itr = quadindexsort.quadpointers.begin(); itr != quadindexsort.quadpointers.end(); itr++) + { + SQuad* quadptr = (*itr); + quadptr->temp.quadoffset = ftell(mainfp) - head.indexoffset - sizeof(FF_3dmmIndexHeader); + quadptr->temp.quadsize = 0; + FF_3dmmIndexQuad indexquad; + indexquad.type = quadptr->quadid.type; + indexquad.id = quadptr->quadid.id; + indexquad.secoffset = quadptr->temp.sectionoffset; + indexquad.mode = GetQuadMode(quadptr); + memcpy(&indexquad.seclength,&quadptr->temp.sectionsize,3); + indexquad.numreferences = quadptr->references.getNumReferences(); + indexquad.timesreferenced = quadptr->timesreferenced; + fwrite(&indexquad,sizeof(FF_3dmmIndexQuad), 1, mainfp); + quadptr->temp.quadsize += sizeof(FF_3dmmIndexQuad); + //References + for (unsigned short refnum = 0; refnum < indexquad.numreferences; refnum++) + { + FF_3dmmIndexReference reference; + if (!quadptr->references.getReference(refnum, &reference)) continue; + fwrite(&reference,sizeof(FF_3dmmIndexReference), 1, mainfp); + quadptr->temp.quadsize += sizeof(FF_3dmmIndexReference); + } + //String + int stringtype = quadptr->string.getStringType(); + int extraBytes = 0; + long zero = 0; + unsigned short stringid; + if (quadptr->string.getStringType()) + { + switch (head.magicnum) + { + case MN_1033: + { + stringid = 0x0303; + fwrite(&stringid, sizeof(unsigned short),1, mainfp); + std::wstring string = quadptr->string.getString(); + int requiredsize = WideCharToMultiByte(CP_ACP,0,string.c_str(), -1, NULL, 0, NULL, NULL); + char *cvString = new char[requiredsize]; + requiredsize = WideCharToMultiByte(CP_ACP,0,string.c_str(), -1, cvString, requiredsize, NULL, NULL); + unsigned char strlen = requiredsize - 1; + fwrite(&strlen, sizeof(unsigned char), 1, mainfp); + fwrite(cvString, sizeof(char),requiredsize,mainfp); + delete [] cvString; + if ((strlen) % 4 == 0) + { + extraBytes = 0; + } + else + { + extraBytes = 4 - ((strlen) % 4); + } + fseek(mainfp,extraBytes,SEEK_CUR); + quadptr->temp.quadsize += 2 + 1 + requiredsize; + break; + } + case MN_1055: + { + stringid = 0x0505; + fwrite(&stringid, sizeof(unsigned short),1, mainfp); + std::wstring string = quadptr->string.getString(); + unsigned short strlen = (unsigned short)string.size(); + fwrite(&strlen, sizeof(unsigned short),1,mainfp); + fwrite(string.c_str(),sizeof(wchar_t),strlen + 1,mainfp); + if ((strlen) % 2 == 0) + { + extraBytes = 2; + } + else + { + extraBytes = 0; + } + fseek(mainfp,extraBytes,SEEK_CUR); + quadptr->temp.quadsize += 2 + 2 + (strlen * 2) + 2; + break; + } + } + } + indexhead.quadindexlen += quadptr->temp.quadsize + extraBytes; //add on quadsize to total quadindex length + + } + head.indexlen += indexhead.quadindexlen; //add on total quadindex length onto total index length + //DIRECTORY writer + for (std::vector::iterator itr = directorysort.quadpointers.begin(); itr != directorysort.quadpointers.end(); itr++) + { + SQuad* quadptr = (*itr); + FF_3dmmDirectoryEntry direntry; + direntry.offset = quadptr->temp.quadoffset; + direntry.length = quadptr->temp.quadsize; + fwrite(&direntry, sizeof(FF_3dmmDirectoryEntry), 1, mainfp); + head.indexlen += sizeof(FF_3dmmDirectoryEntry); + } + head.filelen = fsize(mainfp); + head.filelen2 = head.filelen; + fseek(mainfp,0,SEEK_SET); + fwrite(&head,sizeof(FF_3dmmHeader),1,mainfp); + fgoto(mainfp, head.indexoffset); + fwrite(&indexhead, sizeof(FF_3dmmIndexHeader),1, mainfp); + + fclose(mainfp); + + if (!copy) fpath = path; + return true; +} \ No newline at end of file diff --git a/pencil++2/sections.cpp b/pencil++2/sections.cpp new file mode 100644 index 0000000..5731644 --- /dev/null +++ b/pencil++2/sections.cpp @@ -0,0 +1,24 @@ +#include "pencilclass.h" + +void CQuadSection::setSectionData(BYTE *_sectiondata, size_t _size) +{ + sectiondata = _sectiondata; size = _size; +} +bool CQuadSection::isSectionCompressed() +{ + if (size >= 8) + { + if (sectiondata[0] == 'K' && sectiondata[1] == 'C' && sectiondata[2] == 'D') + { + return true; + } + } + return false; +} + +size_t CQuadSection::getUncompressedSectionDataSize() +{ + if (!isSectionCompressed()) return size; + size_t uncompressedsize = sectiondata[7]+(((int)sectiondata[6])<<8)+(((int)sectiondata[5])<<16) + (((int)sectiondata[4])<<24); + return uncompressedsize; +} \ No newline at end of file diff --git a/pencil++2/sectns.cpp b/pencil++2/sectns.cpp new file mode 100644 index 0000000..e69de29 diff --git a/pencil++2/sorter.cpp b/pencil++2/sorter.cpp new file mode 100644 index 0000000..251bb3e --- /dev/null +++ b/pencil++2/sorter.cpp @@ -0,0 +1,160 @@ +/* 3DMM Pencil++ 2 + Copyright (C) 2005 Frankie Weindel */ +#include "pencilclass.h" + +CQuadPointerSort::CQuadPointerSort() +{ + sorttype = GETQUAD_SECTIONORDERSORT; +} + +unsigned long CQuadPointerSort::getItemNumber(SQuad *quad) +{ + //std::wstringstream ss; + //ss << L"SORT SIZE: " << (unsigned long)quadpointers.size(); + //MessageBox (NULL, ss.str().c_str(), L"EWFREW", MB_OK); + for (std::vector::iterator itr = quadpointers.begin(); itr != quadpointers.end(); itr++) + { + if ((*itr) == quad) + { + return unsigned long(itr - quadpointers.begin()); + } + } +} +void CQuadPointerSort::removePointer(SQuad *quad) +{ + + for (std::vector::iterator itr = quadpointers.begin(); itr != quadpointers.end(); itr++) + { + SQuad *pointer = (*itr); + if (pointer == quad) + { + quadpointers.erase(itr); + return; + } + } + +} + +void CQuadPointerSort::addPointer(SQuad *quad) +{ + switch (sorttype) + { + case GETQUAD_SECTIONORDERSORT: + { + if (quadpointers.size() == 0) + { + quadpointers.push_back(quad); + return; + } + for (std::vector::iterator itr = quadpointers.begin(); itr != quadpointers.end(); itr++) + { + std::vector::iterator itrnext = itr + 1; + if (quad->temp.sectionoffset < (*itr)->temp.sectionoffset) + { + quadpointers.insert(itr,quad); + return; + } + if (itrnext == quadpointers.end()) + { + quadpointers.push_back(quad); + return; + } + } + } + break; + case GETQUAD_QUADORDERSORT: + { + if (quadpointers.size() == 0) + { + quadpointers.push_back(quad); + return; + } + for (std::vector::iterator itr = quadpointers.begin(); itr != quadpointers.end(); itr++) + { + std::vector::iterator itrnext = itr + 1; + if (quad->temp.quadoffset < (*itr)->temp.quadoffset) + { + quadpointers.insert(itr,quad); + return; + } + if (itrnext == quadpointers.end()) + { + quadpointers.push_back(quad); + return; + } + } + } + break; + case GETQUAD_DIRSORT: + { + if (quadpointers.size() == 0) + { + quadpointers.push_back(quad); + return; + } + for (std::vector::iterator itr = quadpointers.begin(); itr != quadpointers.end(); itr++) + { + std::vector::iterator itrnext = itr + 1; + if (quad->quadid.type == (*itr)->quadid.type) + { + if (quad->quadid.id < (*itr)->quadid.id) + { + quadpointers.insert(itr,quad); + return; + } + } + else + { + if (quad->quadid.type < (*itr)->quadid.type) + { + quadpointers.insert(itr,quad); + return; + } + } + if (itrnext == quadpointers.end()) + { + quadpointers.push_back(quad); + return; + } + } + } + } +} + +void CQuadPointerSort::insertPointer(SQuad *quad, unsigned long where) +{ + quadpointers.insert(quadpointers.begin() + where,quad); +} + +void CQuadPointerSort::addPointers(std::vector *quads) +{ + for (std::vector::iterator itr = quads->begin(); itr != quads->end(); itr++) + { + quadpointers.push_back((*itr)); + } + switch (sorttype) + { + case GETQUAD_SECTIONORDERSORT: + std::sort(quadpointers.begin(), quadpointers.end(),SectionOffsetSortPT()); + break; + case GETQUAD_QUADORDERSORT: + std::sort(quadpointers.begin(), quadpointers.end(),IndexAscendingQuadOffsetSort()); + break; + case GETQUAD_DIRSORT: + std::sort(quadpointers.begin(), quadpointers.end(),DirectorySort()); + break; + + } +} + +SQuad* CQuadPointerSort::getQuadPT(unsigned int quadnum) +{ + if (quadnum < quadpointers.size()) + { + return quadpointers[quadnum]; + } + else + { + return NULL; + } +}; \ No newline at end of file diff --git a/pencil++2/sortfind.h b/pencil++2/sortfind.h new file mode 100644 index 0000000..99a8091 --- /dev/null +++ b/pencil++2/sortfind.h @@ -0,0 +1,2 @@ + + diff --git a/pencil++2/usefulfuncs.cpp b/pencil++2/usefulfuncs.cpp new file mode 100644 index 0000000..1f9e698 --- /dev/null +++ b/pencil++2/usefulfuncs.cpp @@ -0,0 +1,180 @@ +/* 3DMM Pencil++ 2 + Copyright (C) 2005 Frankie Weindel */ + +#include "usefulfuncs.h" + +double roundtodecimal(double number, int decimalpoint) +{ + number = number * pow((double)10, (double) decimalpoint); + number = floor(number+0.5); + number = number / pow((double)10, (double) decimalpoint); + return number; +} + +BOOL ResizeWindow(HWND hWnd, short width, short height) +{ + return SetWindowPos(hWnd,NULL,NULL,NULL,width,height,SWP_NOZORDER|SWP_NOMOVE); +} + +BOOL ResizePosWindow(HWND hWnd, short x, short y, short width, short height) +{ + return SetWindowPos(hWnd,NULL,x,y,width,height,SWP_NOZORDER); +} + +BOOL RePosWindow(HWND hWnd, short x, short y) +{ + return SetWindowPos(hWnd,NULL,x,y,NULL,NULL,SWP_NOZORDER|SWP_NOSIZE); +} + +void ConvertFilter(wchar_t *filter) +{ + size_t strlen = wcslen(filter); + for (unsigned int strpos = 0; strpos < strlen; strpos++) + { + if (filter[strpos] == L'|') + { + + filter[strpos] = 0; + } + } +} + +int ShowOpenDlg(HWND hWnd, std::wstring title, std::wstring filter , std::wstring *retfilepath, std::wstring *retfiletitle) +{ + + OPENFILENAME ofn; + wchar_t szFileName[MAX_PATH] = L""; + wchar_t szFileTitle[MAX_PATH] = L""; + size_t fillen = filter.size(); + wchar_t *szFilter = new wchar_t[fillen + 1]; + + //memcpy(szFilter, filter.c_str(), fillen); + for (unsigned int x = 0; x < fillen; x++) + { + szFilter[x] = (filter.c_str())[x]; + } + szFilter[fillen] = 0; + //MessageBox(NULL,szFilter,filter.c_str(),MB_OK); + + //memset(szFileName,0,maxsize); + ConvertFilter(szFilter); + ZeroMemory(&ofn, sizeof(ofn)); + ofn.lStructSize = sizeof(ofn); + ofn.hwndOwner = hWnd; + ofn.lpstrFilter = szFilter; + ofn.lpstrFile = szFileName; + ofn.lpstrFileTitle = szFileTitle; + ofn.nMaxFile = MAX_PATH; + ofn.nMaxFileTitle = MAX_PATH; + //ofn.lpstrInitialDir = szMSKIDSPath; + ofn.Flags = OFN_EXPLORER | OFN_HIDEREADONLY | OFN_FILEMUSTEXIST; + ofn.lpstrDefExt = L""; + ofn.lpstrTitle = title.c_str(); + if(GetOpenFileName(&ofn)) + { + //memcpy(output, szFileName, maxsize); + if (retfilepath != NULL) + { + *retfilepath = szFileName; + } + if (retfiletitle != NULL) + { + *retfiletitle = szFileTitle; + } + return 1; + } + return 0; +} + +int ShowSaveDlg(HWND hWnd, std::wstring title, std::wstring filter, std::wstring defext, std::wstring *retfilepath, std::wstring *retfiletitle) +{ + + OPENFILENAME ofn; + wchar_t szFileName[MAX_PATH] = L""; + wchar_t szFileTitle[MAX_PATH] = L""; + size_t fillen = filter.size(); + wchar_t *szFilter = new wchar_t[fillen + 1]; + + //memcpy(szFilter, filter.c_str(), fillen); + for (unsigned int x = 0; x < fillen; x++) + { + szFilter[x] = (filter.c_str())[x]; + } + szFilter[fillen] = 0; + //MessageBox(NULL,szFilter,filter.c_str(),MB_OK); + wcscpy(szFileName, defext.c_str()); + //memset(szFileName,0,maxsize); + ConvertFilter(szFilter); + ZeroMemory(&ofn, sizeof(ofn)); + ofn.lStructSize = sizeof(ofn); + ofn.hwndOwner = hWnd; + ofn.lpstrFilter = szFilter; + ofn.lpstrFile = szFileName; + ofn.lpstrFileTitle = szFileTitle; + ofn.nMaxFile = MAX_PATH; + ofn.nMaxFileTitle = MAX_PATH; + //ofn.lpstrInitialDir = szMSKIDSPath; + ofn.Flags = OFN_EXPLORER | OFN_HIDEREADONLY | OFN_OVERWRITEPROMPT; + ofn.lpstrDefExt = defext.c_str(); + ofn.lpstrTitle = title.c_str(); + if(GetSaveFileName(&ofn)) + { + //memcpy(output, szFileName, maxsize); + if (retfilepath != NULL) + { + *retfilepath = szFileName; + } + if (retfiletitle != NULL) + { + *retfiletitle = szFileTitle; + } + return 1; + } + return 0; +} + +std::wstring ConvertNumberToString(short number) +{ + std::wstringstream ss; + ss << number; + return ss.str(); +} + +std::wstring ConvertNumberToString(long number) +{ + std::wstringstream ss; + ss << number; + return ss.str(); +} + +std::wstring ConvertNumberToString(unsigned short number) +{ + std::wstringstream ss; + ss << number; + return ss.str(); +} + +std::wstring ConvertNumberToString(unsigned long number) +{ + std::wstringstream ss; + ss << number; + return ss.str(); +} + +std::wstring GetTextFromHWND(HWND hWnd) +{ + unsigned short textlen = (unsigned short)SendMessage(hWnd, WM_GETTEXTLENGTH, 0,0); + wchar_t *buffer = new wchar_t[textlen + 1]; + SendMessage(hWnd, WM_GETTEXT, (WPARAM)textlen+1, (LPARAM)buffer); + std::wstring retstring = buffer; + delete buffer; + return retstring; +} + +unsigned long GetValueFromHWND(HWND hWnd) +{ + unsigned short textlen = (unsigned short)SendMessage(hWnd, WM_GETTEXTLENGTH, 0,0); + wchar_t buffer[11]; + SendMessage(hWnd, WM_GETTEXT, (WPARAM)10+1, (LPARAM)buffer); + return _wtol(buffer); +} \ No newline at end of file diff --git a/pencil++2/usefulfuncs.h b/pencil++2/usefulfuncs.h new file mode 100644 index 0000000..1591a19 --- /dev/null +++ b/pencil++2/usefulfuncs.h @@ -0,0 +1,27 @@ +/* 3DMM Pencil++ 2 + Copyright (C) 2005 Frankie Weindel */ +#ifndef _USEFULFUNCS_H +#define _USEFULFUNCS_H + +#include +#include +#include +#include + +//Functions +double roundtodecimal(double number, int decimalpoint); + +BOOL ResizeWindow(HWND hWnd, short width, short height); +BOOL RePosWindow(HWND hWnd, short x, short y); +BOOL ResizePosWindow(HWND hWnd, short x, short y, short width, short height); +int ShowOpenDlg(HWND hWnd, std::wstring title, std::wstring filter , std::wstring *retfilepath, std::wstring *retfiletitle); +int ShowSaveDlg(HWND hWnd, std::wstring title, std::wstring filter, std::wstring defext, std::wstring *retfilepath, std::wstring *retfiletitle); + +std::wstring ConvertNumberToString(short); +std::wstring ConvertNumberToString(long); +std::wstring ConvertNumberToString(unsigned short); +std::wstring ConvertNumberToString(unsigned long); + +std::wstring GetTextFromHWND(HWND hWnd); +unsigned long GetValueFromHWND(HWND hWnd); +#endif \ No newline at end of file diff --git a/pencil++2/viewhexdlg.cpp b/pencil++2/viewhexdlg.cpp new file mode 100644 index 0000000..9eefc50 --- /dev/null +++ b/pencil++2/viewhexdlg.cpp @@ -0,0 +1,140 @@ +#include "pencil.h" +#include "hex.h" + +hexentry hexdata[256] = HEXCODES; +HFONT hfont; +namespace viewhexchild +{ + HWND hWnd; + HWND hWndHexTxt; +}; + +void GetHex(BYTE *bytearray, unsigned long size, std::wstringstream *ss) +{ + + for (unsigned long pos = 0; pos < size; pos++) + { + (*ss) << hexdata[bytearray[pos]] << L" "; + } +} + +void GetString(BYTE *bytearray, unsigned long size, std::wstringstream *ss) +{ + + for (unsigned long pos = 0; pos < size; pos++) + { + if ((bytearray[pos] >= 0 && bytearray[pos] < 32) || bytearray[pos] == 0xA0) + { + (*ss) << L"."; + } + else + { + (*ss) << (wchar_t)bytearray[pos]; + } + + } +} + +void GetFilePos(unsigned long pos, std::wstringstream *ss) +{ + unsigned char byte1 = unsigned char(pos & 0xffffff); //GOOD + unsigned char byte2 = unsigned char(pos >> 8); + unsigned char byte3 = unsigned char(pos >> 16); + unsigned char byte4 = unsigned char(pos >> 24); + (*ss) << L"0x" << hexdata[byte4] << hexdata[byte3] << hexdata[byte2] << hexdata[byte1] << L": "; +} + +void SetViewHex() +{ + bool compressed = curquad.section.isSectionCompressed(); + BYTE* datapointer; + unsigned long sectsize; + if (compressed) //data is compressed + { + sectsize = (unsigned long)GetSize(curquad.section.getSectionData(), (int)curquad.section.getSectionDataSize()); + datapointer = new BYTE[sectsize]; //create new buffer for decompressed data (delete it later) + DecompressSmart(curquad.section.getSectionData(), (int)curquad.section.getSectionDataSize(), datapointer); //decompress data + } + else //data is not compressed + { + datapointer = curquad.section.getSectionData(); + sectsize = (unsigned long)curquad.section.getSectionDataSize(); + } + const unsigned long bytesPerLine = 16; + std::wstringstream ss; + for (unsigned long bytePos = 0; bytePos < sectsize; bytePos += bytesPerLine) + { + unsigned long bytesThisLine = sectsize - bytePos; + unsigned short gapfill; + if (sectsize - bytePos >= bytesPerLine) { bytesThisLine = bytesPerLine; gapfill = 0; } + else { bytesThisLine = sectsize - bytePos; gapfill = unsigned short(bytesPerLine - bytesThisLine); } + GetFilePos(bytePos,&ss); + GetHex(datapointer + bytePos, bytesThisLine, &ss); + //Fill Gap + for (unsigned short gapnum = 0; gapnum < gapfill; gapnum++) + { + ss << L" "; + } + GetString(datapointer + bytePos, bytesThisLine, &ss); + ss << L"\r\n"; + } + SendMessage(viewhexchild::hWndHexTxt, WM_SETTEXT, 0, (LPARAM)ss.str().c_str()); + tabhexloaded = true; + if (compressed) delete [] datapointer; //delete datapointer if data was compressed + +} + +LRESULT CALLBACK ViewHexDlgProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam) +{ + switch(msg) + { + case WM_INITDIALOG: + { + viewhexchild::hWnd = hWnd; + viewhexchild::hWndHexTxt = GetDlgItem(hWnd,IDC_EDIT1); + + LOGFONT lFont; + + lFont.lfHeight = 10; + lFont.lfWidth = 10; + + lFont.lfEscapement = 0; + lFont.lfOrientation = 0; + lFont.lfWeight = FW_NORMAL; + lFont.lfItalic = FALSE; + lFont.lfUnderline = FALSE; + lFont.lfStrikeOut = FALSE; + lFont.lfCharSet = DEFAULT_CHARSET; + lFont.lfOutPrecision = OUT_DEFAULT_PRECIS; + lFont.lfClipPrecision = CLIP_DEFAULT_PRECIS; + lFont.lfQuality = DEFAULT_QUALITY; + lFont.lfPitchAndFamily = DEFAULT_PITCH; + wcscpy(lFont.lfFaceName, L"FixedSys");//Microsoft Sans Serif + + hfont = CreateFontIndirect(&lFont); + SendMessage(viewhexchild::hWndHexTxt,WM_SETFONT,(WPARAM)hfont,FALSE); + return 1; + } + break; + case WM_QUIT: + case WM_CLOSE: + DeleteObject(hfont); + break; + case WM_SIZE: + { + RECT clientrect; + GetClientRect(hWnd, &clientrect); + short clientwidth = (short)clientrect.right; + short clientheight = (short)clientrect.bottom; + ResizePosWindow(viewhexchild::hWndHexTxt, 4, 5, clientwidth - 10, clientheight - 10); + } + break; + case WM_ERASEBKGND: + return true; + break; + default:; + + } + return 0; +} + diff --git a/pencil++2/xp.manifest b/pencil++2/xp.manifest new file mode 100644 index 0000000..8ad76da --- /dev/null +++ b/pencil++2/xp.manifest @@ -0,0 +1 @@ + An example of windows XP theming.