mirror of
https://github.com/RPCS3/rpcs3.git
synced 2026-06-01 12:15:27 -06:00
PSFLoader improved
This commit is contained in:
parent
37b22ec99d
commit
b2111b3c3d
@ -24,16 +24,16 @@ public:
|
|||||||
|
|
||||||
virtual u64 Write(const void* src, u64 size);
|
virtual u64 Write(const void* src, u64 size);
|
||||||
|
|
||||||
template<typename T> __forceinline bool Write(const T& data)
|
template<typename T> __forceinline bool SWrite(const T& data, u64 size = sizeof(T))
|
||||||
{
|
{
|
||||||
return Write(&data, sizeof(T)) == sizeof(T);
|
return Write(&data, size) == size;
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual u64 Read(void* dst, u64 size);
|
virtual u64 Read(void* dst, u64 size);
|
||||||
|
|
||||||
template<typename T> __forceinline bool Read(T& data)
|
template<typename T> __forceinline bool SRead(T& data, u64 size = sizeof(T))
|
||||||
{
|
{
|
||||||
return Read(&data, sizeof(T)) == sizeof(T);
|
return Read(&data, size) == size;
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual u64 Seek(s64 offset, vfsSeekMode mode = vfsSeekSet);
|
virtual u64 Seek(s64 offset, vfsSeekMode mode = vfsSeekSet);
|
||||||
@ -41,4 +41,4 @@ public:
|
|||||||
virtual bool Eof();
|
virtual bool Eof();
|
||||||
|
|
||||||
virtual bool IsOpened() const;
|
virtual bool IsOpened() const;
|
||||||
};
|
};
|
||||||
|
|||||||
@ -311,6 +311,16 @@ __noinline s32 savedata_op(
|
|||||||
u32 userId,
|
u32 userId,
|
||||||
vm::ptr<CellSaveDataDoneCallback> funcDone)
|
vm::ptr<CellSaveDataDoneCallback> funcDone)
|
||||||
{
|
{
|
||||||
|
// TODO: check arguments
|
||||||
|
|
||||||
|
// try to lock the mutex (not sure how it originally works; std::try_to_lock makes it non-blocking)
|
||||||
|
std::unique_lock<std::mutex> lock(g_savedata_dialog->mutex, std::try_to_lock);
|
||||||
|
|
||||||
|
if (!lock)
|
||||||
|
{
|
||||||
|
return CELL_SAVEDATA_ERROR_BUSY;
|
||||||
|
}
|
||||||
|
|
||||||
static const std::string base_dir = "/dev_hdd0/home/00000001/savedata/"; // TODO: Get the path of the current or specified user
|
static const std::string base_dir = "/dev_hdd0/home/00000001/savedata/"; // TODO: Get the path of the current or specified user
|
||||||
|
|
||||||
vm::stackvar<CellSaveDataCBResult> result(CPU);
|
vm::stackvar<CellSaveDataCBResult> result(CPU);
|
||||||
@ -370,7 +380,7 @@ __noinline s32 savedata_op(
|
|||||||
save_entry.isNew = false;
|
save_entry.isNew = false;
|
||||||
|
|
||||||
save_entry.size = 0;
|
save_entry.size = 0;
|
||||||
for (const auto& entry2 : vfsDir(base_dir + entry->name))
|
for (const auto entry2 : vfsDir(base_dir + entry->name))
|
||||||
{
|
{
|
||||||
save_entry.size += entry2->size;
|
save_entry.size += entry2->size;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -282,6 +282,8 @@ struct SaveDataEntry
|
|||||||
|
|
||||||
struct SaveDataDialogInstance
|
struct SaveDataDialogInstance
|
||||||
{
|
{
|
||||||
|
std::mutex mutex;
|
||||||
|
|
||||||
SaveDataDialogInstance();
|
SaveDataDialogInstance();
|
||||||
virtual ~SaveDataDialogInstance() = default;
|
virtual ~SaveDataDialogInstance() = default;
|
||||||
};
|
};
|
||||||
|
|||||||
4
rpcs3/Gui/SaveDataDialog.cpp
Normal file
4
rpcs3/Gui/SaveDataDialog.cpp
Normal file
@ -0,0 +1,4 @@
|
|||||||
|
#include "stdafx_gui.h"
|
||||||
|
#include "Emu/Memory/Memory.h"
|
||||||
|
|
||||||
|
#include "SaveDataDialog.h"
|
||||||
9
rpcs3/Gui/SaveDataDialog.h
Normal file
9
rpcs3/Gui/SaveDataDialog.h
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "Emu/SysCalls/Modules/cellSaveData.h"
|
||||||
|
|
||||||
|
class SaveDataDialogFrame : public SaveDataDialogInstance
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
|
||||||
|
};
|
||||||
@ -5,66 +5,126 @@
|
|||||||
|
|
||||||
bool PSFLoader::Load(vfsStream& stream)
|
bool PSFLoader::Load(vfsStream& stream)
|
||||||
{
|
{
|
||||||
Close();
|
Clear();
|
||||||
|
|
||||||
// Load Header
|
// load header
|
||||||
if (stream.Read(&m_header, sizeof(PSFHeader)) != sizeof(PSFHeader) || !m_header.CheckMagic())
|
if (!stream.SRead(m_header))
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
m_psfindxs.resize(m_header.psf_entries_num);
|
// check magic
|
||||||
m_entries.resize(m_header.psf_entries_num);
|
if (m_header.magic != *(u32*)"\0PSF")
|
||||||
|
|
||||||
// Load Indices
|
|
||||||
for (u32 i = 0; i < m_header.psf_entries_num; ++i)
|
|
||||||
{
|
{
|
||||||
if (!stream.Read(m_psfindxs[i]))
|
LOG_ERROR(LOADER, "PSFLoader::Load() failed: unknown magic (0x%x)", m_header.magic);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// check version
|
||||||
|
if (m_header.version != 0x101)
|
||||||
|
{
|
||||||
|
LOG_ERROR(LOADER, "PSFLoader::Load() failed: unknown version (0x%x)", m_header.version);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// load indices
|
||||||
|
std::vector<PSFDefTable> indices;
|
||||||
|
|
||||||
|
indices.resize(m_header.entries_num);
|
||||||
|
|
||||||
|
if (!stream.SRead(indices[0], sizeof(PSFDefTable) * m_header.entries_num))
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// load key table
|
||||||
|
if (m_header.off_key_table > m_header.off_data_table)
|
||||||
|
{
|
||||||
|
LOG_ERROR(LOADER, "PSFLoader::Load() failed: off_key_table=0x%x, off_data_table=0x%x", m_header.off_key_table, m_header.off_data_table);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
const u32 key_table_size = m_header.off_data_table - m_header.off_key_table;
|
||||||
|
|
||||||
|
std::unique_ptr<char> keys(new char[key_table_size + 1]);
|
||||||
|
|
||||||
|
stream.Seek(m_header.off_key_table);
|
||||||
|
|
||||||
|
if (stream.Read(keys.get(), key_table_size) != key_table_size)
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
keys.get()[key_table_size] = 0;
|
||||||
|
|
||||||
|
// fill entries
|
||||||
|
m_entries.resize(m_header.entries_num);
|
||||||
|
|
||||||
|
for (u32 i = 0; i < m_header.entries_num; ++i)
|
||||||
|
{
|
||||||
|
m_entries[i].fmt = indices[i].param_fmt;
|
||||||
|
|
||||||
|
if (indices[i].key_off >= key_table_size)
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
m_entries[i].fmt = m_psfindxs[i].psf_param_fmt;
|
m_entries[i].name = keys.get() + indices[i].key_off;
|
||||||
}
|
|
||||||
|
|
||||||
// Load Key Table
|
// load data
|
||||||
for (u32 i = 0; i < m_header.psf_entries_num; ++i)
|
stream.Seek(m_header.off_data_table + indices[i].data_off);
|
||||||
{
|
|
||||||
stream.Seek(m_header.psf_offset_key_table + m_psfindxs[i].psf_key_table_offset);
|
|
||||||
|
|
||||||
int c_pos = 0;
|
if (indices[i].param_fmt == PSF_PARAM_INT && indices[i].param_len == 4 && indices[i].param_max == 4)
|
||||||
|
|
||||||
while (c_pos < sizeof(m_entries[i].name) - 1)
|
|
||||||
{
|
{
|
||||||
char c;
|
// load int data
|
||||||
|
|
||||||
if (!stream.Read(c) || !c)
|
if (!stream.SRead(m_entries[i].vint))
|
||||||
{
|
{
|
||||||
break;
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (indices[i].param_fmt == PSF_PARAM_STR && indices[i].param_max >= indices[i].param_len)
|
||||||
|
{
|
||||||
|
// load str data
|
||||||
|
|
||||||
|
const u32 size = indices[i].param_len;
|
||||||
|
|
||||||
|
std::unique_ptr<char> str(new char[size + 1]);
|
||||||
|
|
||||||
|
if (stream.Read(str.get(), size) != size)
|
||||||
|
{
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
m_entries[i].name[c_pos++] = c;
|
str.get()[size] = 0;
|
||||||
|
|
||||||
|
m_entries[i].vstr = str.get();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
LOG_ERROR(LOADER, "PSFLoader::Load() failed: (i=%d) fmt=0x%x, len=0x%x, max=0x%x", i, indices[i].param_fmt, indices[i].param_len, indices[i].param_max);
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
m_entries[i].name[c_pos] = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Load Data Table
|
|
||||||
for (u32 i = 0; i < m_header.psf_entries_num; ++i)
|
|
||||||
{
|
|
||||||
stream.Seek(m_header.psf_offset_data_table + m_psfindxs[i].psf_data_tbl_offset);
|
|
||||||
stream.Read(m_entries[i].param, m_psfindxs[i].psf_param_len);
|
|
||||||
memset(m_entries[i].param + m_psfindxs[i].psf_param_len, 0, m_psfindxs[i].psf_param_max_len - m_psfindxs[i].psf_param_len);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return (m_loaded = true);
|
return (m_loaded = true);
|
||||||
}
|
}
|
||||||
|
|
||||||
void PSFLoader::Close()
|
bool PSFLoader::Save(vfsStream& stream)
|
||||||
|
{
|
||||||
|
// TODO: Construct m_header
|
||||||
|
|
||||||
|
m_loaded = true;
|
||||||
|
|
||||||
|
// TODO: Save data
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void PSFLoader::Clear()
|
||||||
{
|
{
|
||||||
m_loaded = false;
|
m_loaded = false;
|
||||||
m_header = {};
|
m_header = {};
|
||||||
m_psfindxs.clear();
|
|
||||||
m_entries.clear();
|
m_entries.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -81,26 +141,61 @@ const PSFEntry* PSFLoader::SearchEntry(const std::string& key) const
|
|||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
PSFEntry& PSFLoader::AddEntry(const std::string& key, u16 fmt)
|
||||||
|
{
|
||||||
|
for (auto& entry : m_entries)
|
||||||
|
{
|
||||||
|
if (key == entry.name)
|
||||||
|
{
|
||||||
|
entry.fmt = fmt;
|
||||||
|
return entry;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
PSFEntry new_entry = {};
|
||||||
|
new_entry.fmt = fmt;
|
||||||
|
new_entry.name = key;
|
||||||
|
m_entries.push_back(new_entry);
|
||||||
|
|
||||||
|
return m_entries.back();
|
||||||
|
}
|
||||||
|
|
||||||
std::string PSFLoader::GetString(const std::string& key, std::string def) const
|
std::string PSFLoader::GetString(const std::string& key, std::string def) const
|
||||||
{
|
{
|
||||||
if (const auto entry = SearchEntry(key))
|
if (const auto entry = SearchEntry(key))
|
||||||
{
|
{
|
||||||
return entry->FormatString();
|
if (entry->fmt == PSF_PARAM_STR)
|
||||||
}
|
{
|
||||||
else
|
return entry->vstr;
|
||||||
{
|
}
|
||||||
return def;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return def;
|
||||||
}
|
}
|
||||||
|
|
||||||
u32 PSFLoader::GetInteger(const std::string& key, u32 def) const
|
s32 PSFLoader::GetInteger(const std::string& key, s32 def) const
|
||||||
{
|
{
|
||||||
if (const auto entry = SearchEntry(key))
|
if (const auto entry = SearchEntry(key))
|
||||||
{
|
{
|
||||||
return entry->FormatInteger();
|
if (entry->fmt == PSF_PARAM_INT)
|
||||||
}
|
{
|
||||||
else
|
return entry->vint;
|
||||||
{
|
}
|
||||||
return def;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return def;
|
||||||
|
}
|
||||||
|
|
||||||
|
void PSFLoader::SetString(const std::string& key, std::string value)
|
||||||
|
{
|
||||||
|
auto& entry = AddEntry(key, PSF_PARAM_STR);
|
||||||
|
|
||||||
|
entry.vstr = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
void PSFLoader::SetInteger(const std::string& key, s32 value)
|
||||||
|
{
|
||||||
|
auto& entry = AddEntry(key, PSF_PARAM_INT);
|
||||||
|
|
||||||
|
entry.vint = value;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -4,54 +4,42 @@ struct vfsStream;
|
|||||||
|
|
||||||
struct PSFHeader
|
struct PSFHeader
|
||||||
{
|
{
|
||||||
u32 psf_magic;
|
u32 magic;
|
||||||
u32 psf_version;
|
u32 version;
|
||||||
u32 psf_offset_key_table;
|
u32 off_key_table;
|
||||||
u32 psf_offset_data_table;
|
u32 off_data_table;
|
||||||
u32 psf_entries_num;
|
u32 entries_num;
|
||||||
|
|
||||||
bool CheckMagic() const { return psf_magic == *(u32*)"\0PSF"; }
|
|
||||||
};
|
};
|
||||||
|
|
||||||
struct PSFDefTbl
|
struct PSFDefTable
|
||||||
{
|
{
|
||||||
u16 psf_key_table_offset;
|
u16 key_off;
|
||||||
u16 psf_param_fmt;
|
u16 param_fmt;
|
||||||
u32 psf_param_len;
|
u32 param_len;
|
||||||
u32 psf_param_max_len;
|
u32 param_max;
|
||||||
u32 psf_data_tbl_offset;
|
u32 data_off;
|
||||||
|
};
|
||||||
|
|
||||||
|
enum : u16
|
||||||
|
{
|
||||||
|
PSF_PARAM_UNK = 0x0004,
|
||||||
|
PSF_PARAM_STR = 0x0204,
|
||||||
|
PSF_PARAM_INT = 0x0404,
|
||||||
};
|
};
|
||||||
|
|
||||||
struct PSFEntry
|
struct PSFEntry
|
||||||
{
|
{
|
||||||
char name[128];
|
|
||||||
u16 fmt;
|
u16 fmt;
|
||||||
char param[4096];
|
std::string name;
|
||||||
|
|
||||||
std::string FormatString() const
|
s32 vint;
|
||||||
{
|
std::string vstr;
|
||||||
switch(fmt)
|
|
||||||
{
|
|
||||||
default:
|
|
||||||
case 0x0400:
|
|
||||||
case 0x0402:
|
|
||||||
return std::string(param);
|
|
||||||
case 0x0404:
|
|
||||||
return fmt::Format("0x%x", FormatInteger());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
u32 FormatInteger() const
|
|
||||||
{
|
|
||||||
return *(u32*)param;
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
class PSFLoader
|
class PSFLoader
|
||||||
{
|
{
|
||||||
bool m_loaded = false;
|
bool m_loaded = false;
|
||||||
PSFHeader m_header = {};
|
PSFHeader m_header = {};
|
||||||
std::vector<PSFDefTbl> m_psfindxs;
|
|
||||||
std::vector<PSFEntry> m_entries;
|
std::vector<PSFEntry> m_entries;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
@ -64,7 +52,9 @@ public:
|
|||||||
|
|
||||||
bool Load(vfsStream& stream);
|
bool Load(vfsStream& stream);
|
||||||
|
|
||||||
void Close();
|
bool Save(vfsStream& stream);
|
||||||
|
|
||||||
|
void Clear();
|
||||||
|
|
||||||
operator bool() const
|
operator bool() const
|
||||||
{
|
{
|
||||||
@ -72,6 +62,14 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
const PSFEntry* SearchEntry(const std::string& key) const;
|
const PSFEntry* SearchEntry(const std::string& key) const;
|
||||||
|
|
||||||
|
PSFEntry& PSFLoader::AddEntry(const std::string& key, u16 type);
|
||||||
|
|
||||||
std::string GetString(const std::string& key, std::string def = "") const;
|
std::string GetString(const std::string& key, std::string def = "") const;
|
||||||
u32 GetInteger(const std::string& key, u32 def = 0) const;
|
|
||||||
|
s32 GetInteger(const std::string& key, s32 def = 0) const;
|
||||||
|
|
||||||
|
void SetString(const std::string& key, std::string value);
|
||||||
|
|
||||||
|
void SetInteger(const std::string& key, s32 value);
|
||||||
};
|
};
|
||||||
|
|||||||
@ -22,8 +22,8 @@
|
|||||||
#include "Emu/Io/XInput/XInputPadHandler.h"
|
#include "Emu/Io/XInput/XInputPadHandler.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include "Emu/SysCalls/Modules/cellMsgDialog.h"
|
|
||||||
#include "Gui/MsgDialog.h"
|
#include "Gui/MsgDialog.h"
|
||||||
|
#include "Gui/SaveDataDialog.h"
|
||||||
|
|
||||||
#include "Gui/GLGSFrame.h"
|
#include "Gui/GLGSFrame.h"
|
||||||
#include <wx/stdpaths.h>
|
#include <wx/stdpaths.h>
|
||||||
@ -41,9 +41,10 @@ wxDEFINE_EVENT(wxEVT_DBG_COMMAND, wxCommandEvent);
|
|||||||
IMPLEMENT_APP(Rpcs3App)
|
IMPLEMENT_APP(Rpcs3App)
|
||||||
Rpcs3App* TheApp;
|
Rpcs3App* TheApp;
|
||||||
|
|
||||||
std::string simplify_path(const std::string& path, bool is_dir);
|
extern std::string simplify_path(const std::string& path, bool is_dir);
|
||||||
|
|
||||||
extern std::unique_ptr<MsgDialogInstance> g_msg_dialog;
|
extern std::unique_ptr<MsgDialogInstance> g_msg_dialog;
|
||||||
|
extern std::unique_ptr<SaveDataDialogInstance> g_savedata_dialog;
|
||||||
|
|
||||||
bool Rpcs3App::OnInit()
|
bool Rpcs3App::OnInit()
|
||||||
{
|
{
|
||||||
@ -137,6 +138,7 @@ bool Rpcs3App::OnInit()
|
|||||||
});
|
});
|
||||||
|
|
||||||
g_msg_dialog.reset(new MsgDialogFrame);
|
g_msg_dialog.reset(new MsgDialogFrame);
|
||||||
|
g_savedata_dialog.reset(new SaveDataDialogFrame);
|
||||||
|
|
||||||
TheApp = this;
|
TheApp = this;
|
||||||
SetAppName(_PRGNAME_);
|
SetAppName(_PRGNAME_);
|
||||||
|
|||||||
@ -183,6 +183,7 @@
|
|||||||
<ClCompile Include="Gui\MsgDialog.cpp" />
|
<ClCompile Include="Gui\MsgDialog.cpp" />
|
||||||
<ClCompile Include="Gui\PADManager.cpp" />
|
<ClCompile Include="Gui\PADManager.cpp" />
|
||||||
<ClCompile Include="Gui\RSXDebugger.cpp" />
|
<ClCompile Include="Gui\RSXDebugger.cpp" />
|
||||||
|
<ClCompile Include="Gui\SaveDataDialog.cpp" />
|
||||||
<ClCompile Include="Gui\SaveDataUtility.cpp" />
|
<ClCompile Include="Gui\SaveDataUtility.cpp" />
|
||||||
<ClCompile Include="Gui\TextInputDialog.cpp" />
|
<ClCompile Include="Gui\TextInputDialog.cpp" />
|
||||||
<ClCompile Include="Gui\VFSManager.cpp" />
|
<ClCompile Include="Gui\VFSManager.cpp" />
|
||||||
@ -224,6 +225,7 @@
|
|||||||
<ClInclude Include="Gui\MsgDialog.h" />
|
<ClInclude Include="Gui\MsgDialog.h" />
|
||||||
<ClInclude Include="Gui\RegisterEditor.h" />
|
<ClInclude Include="Gui\RegisterEditor.h" />
|
||||||
<ClInclude Include="Gui\RSXDebugger.h" />
|
<ClInclude Include="Gui\RSXDebugger.h" />
|
||||||
|
<ClInclude Include="Gui\SaveDataDialog.h" />
|
||||||
<ClInclude Include="Gui\SaveDataUtility.h" />
|
<ClInclude Include="Gui\SaveDataUtility.h" />
|
||||||
<ClInclude Include="Gui\TextInputDialog.h" />
|
<ClInclude Include="Gui\TextInputDialog.h" />
|
||||||
<ClInclude Include="Gui\VFSManager.h" />
|
<ClInclude Include="Gui\VFSManager.h" />
|
||||||
|
|||||||
@ -1,4 +1,4 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<Filter Include="Gui">
|
<Filter Include="Gui">
|
||||||
@ -99,6 +99,9 @@
|
|||||||
<ClCompile Include="Gui\CgDisasm.cpp">
|
<ClCompile Include="Gui\CgDisasm.cpp">
|
||||||
<Filter>Gui</Filter>
|
<Filter>Gui</Filter>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
|
<ClCompile Include="Gui\SaveDataDialog.cpp">
|
||||||
|
<Filter>Gui</Filter>
|
||||||
|
</ClCompile>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<ResourceCompile Include="rpcs3.rc" />
|
<ResourceCompile Include="rpcs3.rc" />
|
||||||
@ -200,8 +203,8 @@
|
|||||||
<ClInclude Include="Gui\CgDisasm.h">
|
<ClInclude Include="Gui\CgDisasm.h">
|
||||||
<Filter>Gui</Filter>
|
<Filter>Gui</Filter>
|
||||||
</ClInclude>
|
</ClInclude>
|
||||||
<ClCompile Include="git-version.h">
|
<ClInclude Include="Gui\SaveDataDialog.h">
|
||||||
<Filter>Gui</Filter>
|
<Filter>Gui</Filter>
|
||||||
</ClCompile>
|
</ClInclude>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
</Project>
|
</Project>
|
||||||
Loading…
Reference in New Issue
Block a user