diff --git a/desmume/src/utils/fsnitro.cpp b/desmume/src/utils/fsnitro.cpp index 5e6bc9b73..17d75d52c 100644 --- a/desmume/src/utils/fsnitro.cpp +++ b/desmume/src/utils/fsnitro.cpp @@ -17,9 +17,14 @@ #include #include -#ifndef _MSC_VER +#include +#ifdef _MSC_VER +#include +#define __mkdir(x) mkdir(x) +#else #include #include +#define __mkdir(x) mkdir(x, 0777) #endif #include "fsnitro.h" @@ -373,6 +378,24 @@ bool FS_NITRO::getFileIdByAddr(u32 addr, u16 &id, u32 &offset) return false; } +string FS_NITRO::getDirNameByID(u16 id) +{ + if (!inited) return ""; + if ((id & 0xF000) != 0xF000) return "|file|"; + if ((id & 0x0FFF) > numDirs) return ""; + + return (string)fnt[id & 0x0FFF].filename; +} + +u16 FS_NITRO::getDirParrentByID(u16 id) +{ + if (!inited) return 0xFFFF; + if ((id & 0xF000) != 0xF000) return 0xFFFF; + if ((id & 0x0FFF) > numDirs) return 0xFFFF; + + return fnt[id & 0x0FFF].parentID; +} + string FS_NITRO::getFileNameByID(u16 id) { if (!inited) return ""; @@ -383,7 +406,16 @@ string FS_NITRO::getFileNameByID(u16 id) return (string)fat[id].filename; } -string FS_NITRO::getFullPathByFileID(u16 id) +u16 FS_NITRO::getFileParentById(u16 id) +{ + if (!inited) return 0xFFFF; + if ((id & 0xF000) == 0xF000) return 0xFFFF; + if (id > numFiles) return 0xFFFF; + + return fat[id].parentID; +} + +string FS_NITRO::getFullPathByFileID(u16 id, bool addRoot) { if (!inited) return ""; if (id > numFiles) return ""; @@ -397,10 +429,14 @@ string FS_NITRO::getFullPathByFileID(u16 id) res = fnt[parentID].filename + string(FS_DIRECTORY_DELIMITER_CHAR + res); parentID = (fnt[parentID].parentID & 0x0FFF); } - res = (string)FS_DIRECTORY_DELIMITER_CHAR + (string)"data" + (string)FS_DIRECTORY_DELIMITER_CHAR + res; + if (addRoot) + res = (string)FS_DIRECTORY_DELIMITER_CHAR + (string)"data" + (string)FS_DIRECTORY_DELIMITER_CHAR + res; } else - res = string("\\overlay") + FS_DIRECTORY_DELIMITER_CHAR; + { + if (addRoot) + res = FS_DIRECTORY_DELIMITER_CHAR + string("overlay") + FS_DIRECTORY_DELIMITER_CHAR; + } res += (string)fat[id].filename; return res; @@ -430,3 +466,80 @@ u32 FS_NITRO::getEndAddrById(u16 id) return (fat[id].end); } +bool FS_NITRO::extract(u16 id, string to) +{ + printf("Extract to %s\n", to.c_str()); + + FILE *fp = fopen(to.c_str(), "wb"); + if (fp) + { + fwrite((rom + fat[id].start), 1, fat[id].size, fp); + fclose(fp); + return true; + } + + return false; +} + +bool FS_NITRO::extractFile(u16 id, string to) +{ + if (!inited) return false; + if (id > numFiles) return false; + + char curr_dir[MAX_PATH] = {0}; + getcwd(curr_dir, sizeof(curr_dir)); + chdir(to.c_str()); + extract(id, fat[id].filename); + chdir(curr_dir); + + return true; +} + +bool FS_NITRO::extractAll(string to, void (*callback)(u32 current, u32 num)) +{ + if (!inited) return false; + + string dataDir = to + "data" + FS_DIRECTORY_DELIMITER_CHAR; + string overlayDir = to + "overlay" + FS_DIRECTORY_DELIMITER_CHAR; + __mkdir(dataDir.c_str()); + __mkdir(overlayDir.c_str()); + + char curr_dir[MAX_PATH] = {0}; + getcwd(curr_dir, sizeof(curr_dir)); + chdir(dataDir.c_str()); + + for (u32 i = 0; i < numDirs; i++) + { + string tmp = fnt[i].filename; + u16 parent = (fnt[i].parentID) & 0x0FFF; + + while (parent) + { + tmp = (string)fnt[parent].filename + FS_DIRECTORY_DELIMITER_CHAR + tmp; + parent = (fnt[parent].parentID) & 0x0FFF; + } + __mkdir(tmp.c_str()); + } + + chdir(dataDir.c_str()); + for (u32 i = 0; i < numFiles; i++) + { + if (fat[i].isOverlay) continue; + string fname = getFullPathByFileID(i, false); + extract(i, fname.c_str()); + if (callback) + callback(i, numFiles); + } + + chdir(overlayDir.c_str()); + for (u32 i = 0; i < numFiles; i++) + { + if (!fat[i].isOverlay) continue; + extract(i, fat[i].filename); + } + + chdir(curr_dir); + + return true; +} + diff --git a/desmume/src/utils/fsnitro.h b/desmume/src/utils/fsnitro.h index 95527ffe7..78f010808 100644 --- a/desmume/src/utils/fsnitro.h +++ b/desmume/src/utils/fsnitro.h @@ -115,24 +115,38 @@ private: FNT_TYPES getFNTType(u8 type); bool loadFileTables(); + bool extract(u16 id, string to); + void destroy(); + public: FS_NITRO(u8 *cart_rom); ~FS_NITRO(); - void destroy(); bool getFileIdByAddr(u32 addr, u16 &id); bool getFileIdByAddr(u32 addr, u16 &id, u32 &offset); + + string getDirNameByID(u16 id); + u16 getDirParrentByID(u16 id); + string getFileNameByID(u16 id); - string getFullPathByFileID(u16 id); + string getFullPathByFileID(u16 id, bool addRoot = true); + + u16 getFileParentById(u16 id); u32 getFileSizeById(u16 id); u32 getStartAddrById(u16 id); u32 getEndAddrById(u16 id); + bool isOverlay(u16 id) { if (id > numFiles) return false; return fat[id].isOverlay; } + bool isARM9(u32 addr) { return ((addr >= ARM9exeStart) && (addr < ARM9exeEnd)); } bool isARM7(u32 addr) { return ((addr >= ARM7exeStart) && (addr < ARM7exeEnd)); } bool isFAT(u32 addr) { return ((addr >= FATOff) && (addr < FATEnd)); } + bool rebuildFAT(u32 addr, u32 size, string pathData); bool rebuildFAT(string pathData); u32 getFATRecord(u32 addr); + + bool extractFile(u16 id, string to); + bool extractAll(string to, void (*callback)(u32 current, u32 num) = NULL); u32 getNumDirs() { return numDirs; } u32 getNumFiles() { return numFiles; } diff --git a/desmume/src/windows/CWindow.cpp b/desmume/src/windows/CWindow.cpp index adbd40058..55b40dfc7 100644 --- a/desmume/src/windows/CWindow.cpp +++ b/desmume/src/windows/CWindow.cpp @@ -818,7 +818,7 @@ bool TOOLSCLASS::close() DWORD TOOLSCLASS::doOpen() { GetLastError(); - hwnd = CreateDialogW(hInstance, MAKEINTRESOURCEW(idd), NULL, (DLGPROC) dlgproc); + hwnd = CreateDialog(hInstance, MAKEINTRESOURCE(idd), NULL, (DLGPROC) dlgproc); if (!hwnd) { diff --git a/desmume/src/windows/DeSmuME_2005.vcproj b/desmume/src/windows/DeSmuME_2005.vcproj index 08d0ba347..4716a8345 100644 --- a/desmume/src/windows/DeSmuME_2005.vcproj +++ b/desmume/src/windows/DeSmuME_2005.vcproj @@ -81,7 +81,7 @@ /> + + + + diff --git a/desmume/src/windows/DeSmuME_2008.vcproj b/desmume/src/windows/DeSmuME_2008.vcproj index a8f1c4e37..1e3aa182e 100644 --- a/desmume/src/windows/DeSmuME_2008.vcproj +++ b/desmume/src/windows/DeSmuME_2008.vcproj @@ -168,7 +168,7 @@ /> + + + + @@ -2453,10 +2461,6 @@ - - @@ -2800,6 +2804,22 @@ + + + + + + + + diff --git a/desmume/src/windows/DeSmuME_2010.vcxproj b/desmume/src/windows/DeSmuME_2010.vcxproj index ac3d840d1..bde5ee6bf 100644 --- a/desmume/src/windows/DeSmuME_2010.vcxproj +++ b/desmume/src/windows/DeSmuME_2010.vcxproj @@ -261,7 +261,7 @@ true - directx-x64-ddraw-dinput8-dsound-dxerr8-dxguid.lib;lua51.lib;glib-vc8-x64.lib;zlib-vc8-x64.lib;agg-2.5-x64.lib;vfw32.lib;winmm.lib;opengl32.lib;glu32.lib;ws2_32.lib;user32.lib;gdi32.lib;shell32.lib;comdlg32.lib;shlwapi.lib;%(AdditionalDependencies) + directx-x64-ddraw-dinput8-dsound-dxerr8-dxguid.lib;lua51.lib;glib-vc8-x64.lib;zlib-vc8-x64.lib;agg-2.5-x64.lib;vfw32.lib;winmm.lib;opengl32.lib;glu32.lib;ws2_32.lib;user32.lib;gdi32.lib;shell32.lib;comdlg32.lib;shlwapi.lib;comctl32.lib;%(AdditionalDependencies) $(OutDir)$(ProjectName)_x64_debug.exe .\zlib123;agg;.libs\x64;.libs wpcap.dll;lua51.dll @@ -306,7 +306,7 @@ true - directx-x64-ddraw-dinput8-dsound-dxerr8-dxguid.lib;lua51.lib;glib-vc8-x64.lib;zlib-vc8-x64.lib;agg-2.5-x64.lib;vfw32.lib;winmm.lib;opengl32.lib;glu32.lib;ws2_32.lib;user32.lib;gdi32.lib;shell32.lib;comdlg32.lib;shlwapi.lib;%(AdditionalDependencies) + directx-x64-ddraw-dinput8-dsound-dxerr8-dxguid.lib;lua51.lib;glib-vc8-x64.lib;zlib-vc8-x64.lib;agg-2.5-x64.lib;vfw32.lib;winmm.lib;opengl32.lib;glu32.lib;ws2_32.lib;user32.lib;gdi32.lib;shell32.lib;comdlg32.lib;shlwapi.lib;comctl32.lib;%(AdditionalDependencies) $(OutDir)$(ProjectName)_x64_release.exe .\zlib123;agg;.libs\x64;.libs lua51.dll @@ -351,7 +351,7 @@ true - directx-x64-ddraw-dinput8-dsound-dxerr8-dxguid.lib;lua51.lib;glib-vc8-x64.lib;zlib-vc8-x64.lib;agg-2.5-x64.lib;vfw32.lib;winmm.lib;opengl32.lib;glu32.lib;ws2_32.lib;user32.lib;gdi32.lib;shell32.lib;comdlg32.lib;shlwapi.lib;%(AdditionalDependencies) + directx-x64-ddraw-dinput8-dsound-dxerr8-dxguid.lib;lua51.lib;glib-vc8-x64.lib;zlib-vc8-x64.lib;agg-2.5-x64.lib;vfw32.lib;winmm.lib;opengl32.lib;glu32.lib;ws2_32.lib;user32.lib;gdi32.lib;shell32.lib;comdlg32.lib;shlwapi.lib;comctl32.lib;%(AdditionalDependencies) $(OutDir)$(ProjectName)_x64_dev+.exe .\zlib123;agg;.libs\x64;.libs wpcap.dll;lua51.dll @@ -622,6 +622,7 @@ + @@ -874,6 +875,7 @@ + diff --git a/desmume/src/windows/DeSmuME_2010.vcxproj.filters b/desmume/src/windows/DeSmuME_2010.vcxproj.filters index 6470a4982..201a3dc6c 100644 --- a/desmume/src/windows/DeSmuME_2010.vcxproj.filters +++ b/desmume/src/windows/DeSmuME_2010.vcxproj.filters @@ -804,6 +804,9 @@ Core\utils + + Windows\tools + @@ -1548,6 +1551,9 @@ Core\utils + + Windows\tools + diff --git a/desmume/src/windows/DeSmuME_2012.vcxproj b/desmume/src/windows/DeSmuME_2012.vcxproj index cb8b88103..cf519858b 100644 --- a/desmume/src/windows/DeSmuME_2012.vcxproj +++ b/desmume/src/windows/DeSmuME_2012.vcxproj @@ -272,7 +272,7 @@ true - directx-x64-ddraw-dinput8-dsound-dxerr8-dxguid.lib;lua51.lib;glib-vc8-x64.lib;zlib-vc8-x64.lib;agg-2.5-x64.lib;vfw32.lib;winmm.lib;opengl32.lib;glu32.lib;ws2_32.lib;user32.lib;gdi32.lib;shell32.lib;comdlg32.lib;shlwapi.lib;%(AdditionalDependencies) + directx-x64-ddraw-dinput8-dsound-dxerr8-dxguid.lib;lua51.lib;glib-vc8-x64.lib;zlib-vc8-x64.lib;agg-2.5-x64.lib;vfw32.lib;winmm.lib;opengl32.lib;glu32.lib;ws2_32.lib;user32.lib;gdi32.lib;shell32.lib;comdlg32.lib;shlwapi.lib;comctl32.lib;%(AdditionalDependencies) $(OutDir)$(ProjectName)_x64_debug.exe .\zlib123;agg;.libs\x64;.libs wpcap.dll;lua51.dll @@ -317,7 +317,7 @@ true - directx-x64-ddraw-dinput8-dsound-dxerr8-dxguid.lib;lua51.lib;glib-vc8-x64.lib;zlib-vc8-x64.lib;agg-2.5-x64.lib;vfw32.lib;winmm.lib;opengl32.lib;glu32.lib;ws2_32.lib;user32.lib;gdi32.lib;shell32.lib;comdlg32.lib;shlwapi.lib;%(AdditionalDependencies) + directx-x64-ddraw-dinput8-dsound-dxerr8-dxguid.lib;lua51.lib;glib-vc8-x64.lib;zlib-vc8-x64.lib;agg-2.5-x64.lib;vfw32.lib;winmm.lib;opengl32.lib;glu32.lib;ws2_32.lib;user32.lib;gdi32.lib;shell32.lib;comdlg32.lib;shlwapi.lib;comctl32.lib;%(AdditionalDependencies) $(OutDir)$(ProjectName)_x64_release.exe .\zlib123;agg;.libs\x64;.libs lua51.dll @@ -362,7 +362,7 @@ true - directx-x64-ddraw-dinput8-dsound-dxerr8-dxguid.lib;lua51.lib;glib-vc8-x64.lib;zlib-vc8-x64.lib;agg-2.5-x64.lib;vfw32.lib;winmm.lib;opengl32.lib;glu32.lib;ws2_32.lib;user32.lib;gdi32.lib;shell32.lib;comdlg32.lib;shlwapi.lib;%(AdditionalDependencies) + directx-x64-ddraw-dinput8-dsound-dxerr8-dxguid.lib;lua51.lib;glib-vc8-x64.lib;zlib-vc8-x64.lib;agg-2.5-x64.lib;vfw32.lib;winmm.lib;opengl32.lib;glu32.lib;ws2_32.lib;user32.lib;gdi32.lib;shell32.lib;comdlg32.lib;shlwapi.lib;comctl32.lib;%(AdditionalDependencies) $(OutDir)$(ProjectName)_x64_dev+.exe .\zlib123;agg;.libs\x64;.libs wpcap.dll;lua51.dll @@ -633,6 +633,7 @@ + @@ -885,6 +886,7 @@ + diff --git a/desmume/src/windows/DeSmuME_2012.vcxproj.filters b/desmume/src/windows/DeSmuME_2012.vcxproj.filters index 34f162503..143ce26c7 100644 --- a/desmume/src/windows/DeSmuME_2012.vcxproj.filters +++ b/desmume/src/windows/DeSmuME_2012.vcxproj.filters @@ -796,6 +796,9 @@ Core\utils + + Windows\tools + @@ -1410,6 +1413,9 @@ Core\utils + + Windows\tools + diff --git a/desmume/src/windows/fsnitroView.cpp b/desmume/src/windows/fsnitroView.cpp new file mode 100644 index 000000000..5bd823da5 --- /dev/null +++ b/desmume/src/windows/fsnitroView.cpp @@ -0,0 +1,314 @@ +/* + Copyright (C) 2013 DeSmuME team + + This file is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 2 of the License, or + (at your option) any later version. + + This file is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with the this software. If not, see . +*/ + +#include "resource.h" +#include "../common.h" +#include +#include "fsnitroView.h" +#include "CWindow.h" +#include "../MMU.h" +#include "../path.h" +#include "../utils/fsnitro.h" + +HMENU popupMenu = NULL; +HWND hBar = NULL; +FS_NITRO *fs = NULL; +u32 currentFileID = 0xFFFFFFFF; + +INT CALLBACK BrowseCallbackProc(HWND hwnd, UINT uMsg, LPARAM lp, LPARAM pData) +{ + TCHAR szDir[MAX_PATH]; + + switch(uMsg) + { + case BFFM_INITIALIZED: + SendMessage(hwnd, BFFM_SETSELECTION, TRUE, (LPARAM)path.getpath(path.SLOT1D).c_str()); + break; + + case BFFM_SELCHANGED: + if (SHGetPathFromIDList((LPITEMIDLIST) lp, szDir)) + { + SendMessage(hwnd,BFFM_SETSTATUSTEXT, 0, (LPARAM)szDir); + } + break; + } + return 0; +} + +BOOL CALLBACK ProgressWnd(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) +{ + if (uMsg == WM_INITDIALOG) + { + hBar = GetDlgItem(hWnd, IDC_PROGRESS_BAR); + SendMessage(hBar, PBM_SETRANGE32, 0, fs->getNumFiles()); + SendMessage(hBar, PBM_SETPOS, 0, 0); + SendMessage(hBar, PBM_SETSTEP, 1, 0); + SetWindowText(GetDlgItem(hWnd, IDC_MESSAGE), "Please, wait..."); + SetWindowText(hWnd, "Extracting..."); + return FALSE; + } + return FALSE; +} + +void extractCallback(u32 current, u32 num) +{ + if (hBar) + SendMessage(hBar, PBM_SETPOS, current, 0); +} + +BOOL CALLBACK ViewFSNitroProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) +{ + switch (uMsg) + { + case WM_INITDIALOG: + { + fs = new FS_NITRO(MMU.CART_ROM); + if (!fs) + { + msgbox->error("Error reading FS from ROM"); + SendMessage(hWnd, WM_CLOSE, 0, 0); + return TRUE; + } + + HWND tree = GetDlgItem(hWnd, IDC_FILES_TREE); + + //HBITMAP hBmp; + HICON hIcon = NULL; + HIMAGELIST hIml = ImageList_Create(16, 16, ILC_COLORDDB | ILC_HIGHQUALITYSCALE, 3, 0); + // Open folder icon + hIcon = LoadIcon(hAppInst, MAKEINTRESOURCE(IDI_FOLDER_OPEN)); + int iFolderOpen = ImageList_AddIcon(hIml, hIcon); + DeleteObject(hIcon); + // Closed folder icon + hIcon = LoadIcon(hAppInst, MAKEINTRESOURCE(IDI_FOLDER_CLOSED)); + int iFolderClosed = ImageList_AddIcon(hIml, hIcon); + DeleteObject(hIcon); + // Binary file icon + hIcon = LoadIcon(hAppInst, MAKEINTRESOURCE(IDI_FILE_BINARY)); + int iFileBinary = ImageList_AddIcon(hIml, hIcon); + DeleteObject(hIcon); + + TreeView_SetImageList(tree, hIml, TVSIL_NORMAL); + + const u32 numDirs = fs->getNumDirs(); + const u32 numFiles = fs->getNumFiles(); + HTREEITEM *dirs = new HTREEITEM[numDirs]; + memset(dirs, 0, sizeof(HTREEITEM) * numDirs); + + //printf("Dirs: %d\n", numDirs); + //printf("Files: %d\n", numFiles); + + TVINSERTSTRUCT item; + // data folder + memset(&item, 0, sizeof(TVINSERTSTRUCT)); + item.hParent = TVI_ROOT; + item.item.mask = TVIF_TEXT | TVIF_IMAGE | TVIF_SELECTEDIMAGE | TVIF_PARAM;; + item.item.pszText = (LPSTR)"data"; + item.item.iImage = iFolderOpen; + item.item.iSelectedImage = iFolderClosed; + item.item.lParam = 0xFFFF; + HTREEITEM hData = TreeView_InsertItem(tree, &item); + + // overlay folder + memset(&item, 0, sizeof(TVINSERTSTRUCT)); + item.hParent = TVI_ROOT; + item.item.mask = TVIF_TEXT | TVIF_IMAGE | TVIF_SELECTEDIMAGE | TVIF_PARAM;; + item.item.pszText = (LPSTR)"overlay"; + item.item.iImage = iFolderOpen; + item.item.iSelectedImage = iFolderClosed; + item.item.lParam = 0xFFFE; + HTREEITEM hOverlay = TreeView_InsertItem(tree, &item); + + for (u32 i = 1; i < numDirs; i++) + { + u16 id = (i | 0xF000); + u16 parent = fs->getDirParrentByID(id) & 0x0FFF; + + string name = fs->getDirNameByID(id); + //printf("%s\n", name.c_str()); + TVINSERTSTRUCT item; + memset(&item, 0, sizeof(item)); + if (parent == 0) + item.hParent = hData; + else + item.hParent = dirs[parent]; + + item.item.mask = TVIF_TEXT | TVIF_IMAGE | TVIF_SELECTEDIMAGE | TVIF_PARAM; + item.item.pszText = (LPSTR)name.c_str(); + item.item.iImage = iFolderOpen; + item.item.iSelectedImage = iFolderClosed; + item.item.lParam = id; + + dirs[i] = TreeView_InsertItem(tree, &item); + } + + for (u32 i = 0; i < numFiles; i++) + { + u16 parent = fs->getFileParentById(i); + if (parent == 0xFFFF) continue; + + parent &= 0x0FFF; + + string name = fs->getFileNameByID(i); + TVINSERTSTRUCT item; + memset(&item, 0, sizeof(item)); + if (fs->isOverlay(i)) + { + item.hParent = hOverlay; + } + else + { + if (parent == 0) + item.hParent = hData; + else + item.hParent = dirs[parent]; + } + + item.item.mask = TVIF_TEXT | TVIF_IMAGE | TVIF_SELECTEDIMAGE | TVIF_PARAM; + item.item.pszText = (LPSTR)name.c_str(); + item.item.iImage = iFileBinary; + item.item.iSelectedImage = iFileBinary; + item.item.lParam = i; + TreeView_InsertItem(tree, &item); + } + delete [] dirs; + + popupMenu = LoadMenu(hAppInst, MAKEINTRESOURCE(MENU_FSNITRO)); + } + return FALSE; + + case WM_CLOSE: + if (fs) + { + delete fs; + fs = NULL; + } + if (popupMenu) + { + DestroyMenu(popupMenu); + popupMenu = NULL; + } + PostQuitMessage(0); + return TRUE; + + case WM_COMMAND: + switch(LOWORD(wParam)) + { + case IDCANCEL: + SendMessage(hWnd, WM_CLOSE, 0, 0); + return TRUE; + + case ID_EXTRACTFILE: + case ID_EXTRACTALL: + { + char tmp_path[MAX_PATH] = {0}; + + BROWSEINFO bp={0}; + memset(&bp, 0, sizeof(bp)); + bp.hwndOwner = hWnd; + bp.pidlRoot = NULL; + bp.pszDisplayName = NULL; + bp.lpszTitle = "Select destination directory"; + bp.ulFlags = BIF_RETURNONLYFSDIRS | BIF_NEWDIALOGSTYLE | BIF_USENEWUI; + bp.lpfn = BrowseCallbackProc; + + LPITEMIDLIST tmp = SHBrowseForFolder((LPBROWSEINFO)&bp); + if (tmp) + { + memset(tmp_path, 0, sizeof(tmp_path)); + SHGetPathFromIDList(tmp, tmp_path); + if (tmp_path[strlen(tmp_path)-1] != '\\') + tmp_path[strlen(tmp_path)] = '\\'; + + if (LOWORD(wParam) == ID_EXTRACTALL) + { + string tmp = (string)tmp_path + (string)path.GetRomNameWithoutExtension() + (string)"\\"; + mkdir(tmp.c_str()); + HWND progress = CreateDialog(hAppInst, MAKEINTRESOURCE(IDD_PROGRESS_WND), NULL, (DLGPROC)ProgressWnd); + ShowWindow(progress, SW_SHOW); + UpdateWindow(progress); + fs->extractAll(tmp, extractCallback); + DestroyWindow(progress); + } + else + { + if (currentFileID < 0xF000) + fs->extractFile(currentFileID, (string)tmp_path); + } + } + } + return TRUE; + } + return FALSE; + + case WM_NOTIFY: + { + LPNMHDR notify = (LPNMHDR)lParam; + if (wParam == IDC_FILES_TREE) + { + switch (notify->code) + { + case NM_RCLICK: + { + + HTREEITEM hItem = TreeView_GetNextItem(notify->hwndFrom, 0, TVGN_DROPHILITE); + if(hItem) + TreeView_SelectItem(notify->hwndFrom, hItem); + TVITEM pitem; + HTREEITEM item = TreeView_GetSelection(GetDlgItem(hWnd, IDC_FILES_TREE)); + + memset(&pitem, 0, sizeof(pitem)); + pitem.hItem = item; + pitem.mask = TVIF_PARAM; + TreeView_GetItem(GetDlgItem(hWnd, IDC_FILES_TREE), &pitem); + + currentFileID = pitem.lParam; + EnableMenuItem(popupMenu, ID_EXTRACTFILE, MF_BYCOMMAND | ((currentFileID < 0xF000)?MF_ENABLED:MF_GRAYED)); + DWORD tmp = GetMessagePos(); + POINTS pos = MAKEPOINTS(tmp); + TrackPopupMenu(GetSubMenu(popupMenu, 0), TPM_LEFTALIGN | TPM_RIGHTBUTTON, pos.x, pos.y, NULL, hWnd, NULL); + } + break; + + case TVN_SELCHANGED: + { + LPNMTREEVIEW sel = (LPNMTREEVIEW)lParam; + char buf[256] = {0}; + + u16 id = sel->itemNew.lParam; + + if ((id & 0xF000) == 0xF000) + { + SetWindowText(GetDlgItem(hWnd, IDC_FILE_INFO), ""); + } + else + { + u32 start = fs->getStartAddrById(id); + u32 end = fs->getEndAddrById(id); + u32 size = (end - start); + sprintf(buf, "[%08X-%08X] size %d", start, end, size); + SetWindowText(GetDlgItem(hWnd, IDC_FILE_INFO), buf); + } + } + break; + } + } + } + return FALSE; + } + return FALSE; +} \ No newline at end of file diff --git a/desmume/src/windows/fsnitroView.h b/desmume/src/windows/fsnitroView.h new file mode 100644 index 000000000..8a0f043eb --- /dev/null +++ b/desmume/src/windows/fsnitroView.h @@ -0,0 +1,24 @@ +/* + Copyright (C) 2013 DeSmuME team + + This file is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 2 of the License, or + (at your option) any later version. + + This file is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with the this software. If not, see . +*/ + +#ifndef _FSNITROVIEW_H_ +#define _FSNITROVIEW_H_ +#include "../types.h" + +extern BOOL CALLBACK ViewFSNitroProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam); + +#endif diff --git a/desmume/src/windows/main.cpp b/desmume/src/windows/main.cpp index 67baaeb9e..c0fed322a 100644 --- a/desmume/src/windows/main.cpp +++ b/desmume/src/windows/main.cpp @@ -109,6 +109,7 @@ #include "aviout.h" #include "soundView.h" #include "importSave.h" +#include "fsnitroView.h" // //static size_t heapram = 0; //void* operator new[](size_t amt) @@ -477,6 +478,7 @@ TOOLSCLASS *ViewMaps = NULL; TOOLSCLASS *ViewOAM = NULL; TOOLSCLASS *ViewMatrices = NULL; TOOLSCLASS *ViewLights = NULL; +TOOLSCLASS *ViewFSNitro = NULL; volatile bool execute = false; volatile bool paused = true; @@ -3192,6 +3194,7 @@ int _main() ViewOAM = new TOOLSCLASS(hAppInst, IDD_OAM, (DLGPROC) ViewOAMProc); ViewMatrices = new TOOLSCLASS(hAppInst, IDD_MATRIX_VIEWER, (DLGPROC) ViewMatricesProc); ViewLights = new TOOLSCLASS(hAppInst, IDD_LIGHT_VIEWER, (DLGPROC) ViewLightsProc); + ViewFSNitro = new TOOLSCLASS(hAppInst, IDD_TOOL_FSNITRO, (DLGPROC) ViewFSNitroProc); // Slot 1 / Slot 2 (GBA slot) cmdline.slot1_fat_dir = GetPrivateProfileStdString("Slot1", "fat_path", ""); @@ -3485,6 +3488,7 @@ int _main() SoundView_DeInit(); //if (input!=NULL) delete input; + if (ViewFSNitro!=NULL) delete ViewFSNitro; if (ViewLights!=NULL) delete ViewLights; if (ViewMatrices!=NULL) delete ViewMatrices; if (ViewOAM!=NULL) delete ViewOAM; @@ -4456,6 +4460,8 @@ LRESULT CALLBACK WindowProcedure (HWND hwnd, UINT message, WPARAM wParam, LPARAM //Gray the recent ROM menu item if there are no recent ROMs DesEnableMenuItem(mainMenu, ID_FILE_RECENTROM, RecentRoms.size()>0); + DesEnableMenuItem(mainMenu, ID_TOOLS_VIEWFSNITRO, romloaded); + //Updated Checked menu items //language choices @@ -5633,6 +5639,10 @@ DOKEYDOWN: case IDM_LIGHT_VIEWER: ViewLights->open(); return 0; + + case ID_TOOLS_VIEWFSNITRO: + ViewFSNitro->open(); + return 0; //========================================================== Tools end case IDM_MGPU: diff --git a/desmume/src/windows/resource.h b/desmume/src/windows/resource.h index a0acbea17..cbde8bbf1 100644 --- a/desmume/src/windows/resource.h +++ b/desmume/src/windows/resource.h @@ -51,14 +51,21 @@ #define IDM_SBG3 127 #define IDD_DIALOG1 127 #define IDM_OAM 128 +#define IDD_TOOL_FSNITRO 128 +#define IDR_POPUPM_FSNITRO 128 #define IDM_PRINTSCREEN 129 +#define MENU_FSNITRO 129 #define IDM_QUICK_PRINTSCREEN 130 #define IDM_SOUNDSETTINGS 131 +#define IDD_PROGRESS_WND 131 #define IDM_WEBSITE 132 #define IDM_FORUM 133 #define IDM_SUBMITBUGREPORT 134 #define IDM_STATE_LOAD 135 #define IDM_STATE_SAVE 136 +#define IDI_FOLDER_OPEN 136 +#define IDI_FOLDER_CLOSED 137 +#define IDI_FILE_BINARY 138 #define IDM_STATE_SAVE_F10 139 #define IDM_STATE_SAVE_F1 140 #define IDM_STATE_SAVE_F2 141 @@ -443,8 +450,12 @@ #define IDC_DIRECTORY_SCAN 1056 #define IDC_BADD_AR 1057 #define IDC_IMP_INFO_FILE 1057 +#define IDC_FILES_TREE 1057 +#define IDC_PROGRESS_BAR 1057 #define IDC_BADD_CB 1058 #define IDC_IMP_INFO_ADVANSCENE 1058 +#define IDC_FILE_INFO 1058 +#define IDC_MESSAGE 1058 #define IDC_IMP_MANUAL_SIZE 1059 #define IDC_BREMOVE 1060 #define IDC_BEDIT 1061 @@ -921,6 +932,9 @@ #define ID_DISPLAYMETHOD_FILTER 40106 #define IDC_VIEW_PADTOINTEGER 40107 #define ID_TOOLS_VIEWFSNITRO 40108 +#define ID_EXTRACTFILE 40109 +#define ID_EXTRACTALL 40110 +#define ID_CLOSE 40111 #define ID_LABEL_HK3b 44670 #define ID_LABEL_HK3c 44671 #define ID_LABEL_HK3d 44672 @@ -1025,6 +1039,7 @@ // #ifdef APSTUDIO_INVOKED #ifndef APSTUDIO_READONLY_SYMBOLS +#define _APS_NO_MFC 1 #define _APS_NEXT_RESOURCE_VALUE 128 #define _APS_NEXT_COMMAND_VALUE 40109 #define _APS_NEXT_CONTROL_VALUE 1057 diff --git a/desmume/src/windows/resources.rc b/desmume/src/windows/resources.rc index 161e3b847..d471ccf2c 100644 Binary files a/desmume/src/windows/resources.rc and b/desmume/src/windows/resources.rc differ