Merge pull request #814 from Nekotekina/master

declCPU removed, PPUThread& is passed as argument
This commit is contained in:
Alexandro Sánchez Bach 2014-09-17 17:31:45 +02:00
commit 279ec3d8a3
30 changed files with 183 additions and 162 deletions

View file

@ -123,7 +123,7 @@ static struct { inline operator Log::LogType() { return Log::LogType::PPU; } } P
static struct { inline operator Log::LogType() { return Log::LogType::SPU; } } SPU; static struct { inline operator Log::LogType() { return Log::LogType::SPU; } } SPU;
static struct { inline operator Log::LogType() { return Log::LogType::TTY; } } TTY; static struct { inline operator Log::LogType() { return Log::LogType::TTY; } } TTY;
inline void log_message(Log::LogType type, Log::LogSeverity sev, std::string text) inline void log_message(Log::LogType type, Log::LogSeverity sev, const char* text)
{ {
//another msvc bug makes this not work, uncomment this and delete everything else in this function when it's fixed //another msvc bug makes this not work, uncomment this and delete everything else in this function when it's fixed
//Log::LogManager::getInstance().log({logType, severity, text}) //Log::LogManager::getInstance().log({logType, severity, text})
@ -133,8 +133,8 @@ inline void log_message(Log::LogType type, Log::LogSeverity sev, std::string tex
} }
template<typename T, typename ...Ts> template<typename T, typename ...Ts>
inline void log_message(Log::LogType type, Log::LogSeverity sev, std::string text, T arg, Ts... args) inline void log_message(Log::LogType type, Log::LogSeverity sev, const char* text, T arg, Ts... args)
{ {
Log::LogMessage msg{type, sev, fmt::Format(text,arg,args...)}; Log::LogMessage msg{type, sev, fmt::Format(text, arg, args...)};
Log::LogManager::getInstance().log(msg); Log::LogManager::getInstance().log(msg);
} }

View file

@ -4,38 +4,6 @@
extern const std::string fmt::placeholder = "???"; extern const std::string fmt::placeholder = "???";
//wrapper to deal with advance sprintf formating options with automatic length finding
//can't take strings by reference because of "va_start", so overload it with char *
std::string fmt::FormatV(const char *fmt, va_list args)
{
size_t length = 256;
std::string str;
for (;;)
{
std::vector<char> buffptr(length);
#if !defined(_MSC_VER)
size_t printlen = vsnprintf(buffptr.data(), length, fmt, args);
#else
size_t printlen = vsnprintf_s(buffptr.data(), length, length - 1, fmt, args);
#endif
if (printlen < length)
{
str = std::string(buffptr.data(), printlen);
break;
}
length *= 2;
}
return str;
}
std::string fmt::FormatV(std::string fmt, va_list args)
{
std::string str = FormatV(fmt.c_str(), args);
return str;
}
std::string replace_first(const std::string& src, const std::string& from, const std::string& to) std::string replace_first(const std::string& src, const std::string& from, const std::string& to)
{ {
auto pos = src.find(from); auto pos = src.find(from);

View file

@ -96,15 +96,9 @@ namespace fmt{
template<typename T> template<typename T>
T by_value(T x) { return x; } T by_value(T x) { return x; }
//wrapper to deal with advance sprintf formating options with automatic length finding
//can't take strings by reference because of "va_start", so overload it with char *
string FormatV(const char *fmt, va_list args);
string FormatV(string fmt, va_list args);
//wrapper to deal with advance sprintf formating options with automatic length finding //wrapper to deal with advance sprintf formating options with automatic length finding
template<typename ... Args> template<typename ... Args>
string Format(const string &fmt, Args ... parameters) string Format(const char* fmt, Args ... parameters)
{ {
size_t length = 256; size_t length = 256;
string str; string str;
@ -115,10 +109,10 @@ namespace fmt{
#if !defined(_MSC_VER) #if !defined(_MSC_VER)
#pragma clang diagnostic push #pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wformat-security" #pragma clang diagnostic ignored "-Wformat-security"
size_t printlen = snprintf(buffptr.data(), length, fmt.c_str(), std::forward<Args>(parameters)...); size_t printlen = snprintf(buffptr.data(), length, fmt, std::forward<Args>(parameters)...);
#pragma clang diagnostic pop #pragma clang diagnostic pop
#else #else
size_t printlen = _snprintf_s(buffptr.data(), length, length - 1, fmt.c_str(), std::forward<Args>(parameters)...); size_t printlen = _snprintf_s(buffptr.data(), length, length - 1, fmt, std::forward<Args>(parameters)...);
#endif #endif
if (printlen < length) if (printlen < length)
{ {

View file

@ -243,13 +243,10 @@ void CPUThread::Stop()
m_status = Stopped; m_status = Stopped;
if(CPUThread* thr = GetCurrentCPUThread()) if(static_cast<NamedThreadBase*>(this) != GetCurrentNamedThread())
{ {
if(thr->GetId() != GetId())
ThreadBase::Stop();
}
else
ThreadBase::Stop(); ThreadBase::Stop();
}
Emu.CheckStatus(); Emu.CheckStatus();

View file

@ -68,7 +68,7 @@ private:
const u64 old_sc = CPU.m_last_syscall; const u64 old_sc = CPU.m_last_syscall;
CPU.m_last_syscall = sc; CPU.m_last_syscall = sc;
SysCalls::DoSyscall((u32)sc); SysCalls::DoSyscall(CPU, (u32)sc);
if(Ini.HLELogging.GetValue()) if(Ini.HLELogging.GetValue())
{ {
@ -2093,7 +2093,7 @@ private:
case 0x1: UNK(fmt::Format("HyperCall %d", CPU.GPR[0])); break; case 0x1: UNK(fmt::Format("HyperCall %d", CPU.GPR[0])); break;
case 0x2: SysCall(); break; case 0x2: SysCall(); break;
case 0x3: case 0x3:
Emu.GetSFuncManager().StaticExecute((u32)CPU.GPR[11]); Emu.GetSFuncManager().StaticExecute(CPU, (u32)CPU.GPR[11]);
if (Ini.HLELogging.GetValue()) if (Ini.HLELogging.GetValue())
{ {
LOG_NOTICE(PPU, "'%s' done with code[0x%llx]! #pc: 0x%x", LOG_NOTICE(PPU, "'%s' done with code[0x%llx]! #pc: 0x%x",
@ -3983,7 +3983,7 @@ private:
void UNK(const std::string& err, bool pause = true) void UNK(const std::string& err, bool pause = true)
{ {
LOG_ERROR(PPU, err + fmt::Format(" #pc: 0x%x", CPU.PC)); LOG_ERROR(PPU, "%s #pc: 0x%x", err.c_str(), CPU.PC);
if(!pause) return; if(!pause) return;
@ -3992,17 +3992,17 @@ private:
for(uint i=0; i<32; ++i) LOG_NOTICE(PPU, "r%d = 0x%llx", i, CPU.GPR[i]); for(uint i=0; i<32; ++i) LOG_NOTICE(PPU, "r%d = 0x%llx", i, CPU.GPR[i]);
for(uint i=0; i<32; ++i) LOG_NOTICE(PPU, "f%d = %llf", i, CPU.FPR[i]); for(uint i=0; i<32; ++i) LOG_NOTICE(PPU, "f%d = %llf", i, CPU.FPR[i]);
for(uint i=0; i<32; ++i) LOG_NOTICE(PPU, "v%d = 0x%s [%s]", i, CPU.VPR[i].to_hex().c_str(), CPU.VPR[i].to_xyzw().c_str()); for(uint i=0; i<32; ++i) LOG_NOTICE(PPU, "v%d = 0x%s [%s]", i, CPU.VPR[i].to_hex().c_str(), CPU.VPR[i].to_xyzw().c_str());
LOG_NOTICE(PPU, "CR = 0x%08x", CPU.CR); LOG_NOTICE(PPU, "CR = 0x%08x", CPU.CR.CR);
LOG_NOTICE(PPU, "LR = 0x%llx", CPU.LR); LOG_NOTICE(PPU, "LR = 0x%llx", CPU.LR);
LOG_NOTICE(PPU, "CTR = 0x%llx", CPU.CTR); LOG_NOTICE(PPU, "CTR = 0x%llx", CPU.CTR);
LOG_NOTICE(PPU, "XER = 0x%llx [CA=%lld | OV=%lld | SO=%lld]", CPU.XER, fmt::by_value(CPU.XER.CA), fmt::by_value(CPU.XER.OV), fmt::by_value(CPU.XER.SO)); LOG_NOTICE(PPU, "XER = 0x%llx [CA=%lld | OV=%lld | SO=%lld]", CPU.XER.XER, fmt::by_value(CPU.XER.CA), fmt::by_value(CPU.XER.OV), fmt::by_value(CPU.XER.SO));
LOG_NOTICE(PPU, "FPSCR = 0x%x " LOG_NOTICE(PPU, "FPSCR = 0x%x "
"[RN=%d | NI=%d | XE=%d | ZE=%d | UE=%d | OE=%d | VE=%d | " "[RN=%d | NI=%d | XE=%d | ZE=%d | UE=%d | OE=%d | VE=%d | "
"VXCVI=%d | VXSQRT=%d | VXSOFT=%d | FPRF=%d | " "VXCVI=%d | VXSQRT=%d | VXSOFT=%d | FPRF=%d | "
"FI=%d | FR=%d | VXVC=%d | VXIMZ=%d | " "FI=%d | FR=%d | VXVC=%d | VXIMZ=%d | "
"VXZDZ=%d | VXIDI=%d | VXISI=%d | VXSNAN=%d | " "VXZDZ=%d | VXIDI=%d | VXISI=%d | VXSNAN=%d | "
"XX=%d | ZX=%d | UX=%d | OX=%d | VX=%d | FEX=%d | FX=%d]", "XX=%d | ZX=%d | UX=%d | OX=%d | VX=%d | FEX=%d | FX=%d]",
CPU.FPSCR, CPU.FPSCR.FPSCR,
fmt::by_value(CPU.FPSCR.RN), fmt::by_value(CPU.FPSCR.RN),
fmt::by_value(CPU.FPSCR.NI), fmt::by_value(CPU.FPSCR.XE), fmt::by_value(CPU.FPSCR.ZE), fmt::by_value(CPU.FPSCR.UE), fmt::by_value(CPU.FPSCR.OE), fmt::by_value(CPU.FPSCR.VE), fmt::by_value(CPU.FPSCR.NI), fmt::by_value(CPU.FPSCR.XE), fmt::by_value(CPU.FPSCR.ZE), fmt::by_value(CPU.FPSCR.UE), fmt::by_value(CPU.FPSCR.OE), fmt::by_value(CPU.FPSCR.VE),
fmt::by_value(CPU.FPSCR.VXCVI), fmt::by_value(CPU.FPSCR.VXSQRT), fmt::by_value(CPU.FPSCR.VXSOFT), fmt::by_value(CPU.FPSCR.FPRF), fmt::by_value(CPU.FPSCR.VXCVI), fmt::by_value(CPU.FPSCR.VXSQRT), fmt::by_value(CPU.FPSCR.VXSOFT), fmt::by_value(CPU.FPSCR.FPRF),

View file

@ -807,5 +807,3 @@ protected:
}; };
PPUThread& GetCurrentPPUThread(); PPUThread& GetCurrentPPUThread();
#define declCPU PPUThread& CPU = GetCurrentPPUThread

View file

@ -1497,7 +1497,7 @@ private:
void UNK(const std::string& err) void UNK(const std::string& err)
{ {
LOG_ERROR(Log::SPU, err + fmt::Format(" #pc: 0x%x", CPU.PC)); LOG_ERROR(Log::SPU, "%s #pc: 0x%x", err.c_str(), CPU.PC);
Emu.Pause(); Emu.Pause();
for(uint i=0; i<128; ++i) LOG_NOTICE(Log::SPU, "r%d = 0x%s", i, CPU.GPR[i].to_hex().c_str()); for(uint i=0; i<128; ++i) LOG_NOTICE(Log::SPU, "r%d = 0x%s", i, CPU.GPR[i].to_hex().c_str());
} }

View file

@ -3779,7 +3779,7 @@ private:
void UNK(const std::string& err) void UNK(const std::string& err)
{ {
LOG_ERROR(Log::SPU, err + fmt::Format(" #pc: 0x%x", CPU.PC)); LOG_ERROR(Log::SPU, "%s #pc: 0x%x", err.c_str(), CPU.PC);
c.mov(cpu_dword(PC), CPU.PC); c.mov(cpu_dword(PC), CPU.PC);
do_finalize = true; do_finalize = true;
Emu.Pause(); Emu.Pause();

View file

@ -589,7 +589,7 @@ void SPUThread::WriteChannel(u32 ch, const u128& r)
return; return;
} }
if (!port.eq->events.push(SYS_SPU_THREAD_EVENT_USER_KEY, GetCurrentCPUThread()->GetId(), ((u64)spup << 32) | (v & 0x00ffffff), data)) if (!port.eq->events.push(SYS_SPU_THREAD_EVENT_USER_KEY, GetId(), ((u64)spup << 32) | (v & 0x00ffffff), data))
{ {
SPU.In_MBox.PushUncond(CELL_EBUSY); SPU.In_MBox.PushUncond(CELL_EBUSY);
return; return;
@ -627,7 +627,7 @@ void SPUThread::WriteChannel(u32 ch, const u128& r)
} }
// TODO: check passing spup value // TODO: check passing spup value
if (!port.eq->events.push(SYS_SPU_THREAD_EVENT_USER_KEY, GetCurrentCPUThread()->GetId(), ((u64)spup << 32) | (v & 0x00ffffff), data)) if (!port.eq->events.push(SYS_SPU_THREAD_EVENT_USER_KEY, GetId(), ((u64)spup << 32) | (v & 0x00ffffff), data))
{ {
LOG_WARNING(Log::SPU, "sys_spu_thread_throw_event(spup=%d, data0=0x%x, data1=0x%x) failed (queue is full)", spup, (v & 0x00ffffff), data); LOG_WARNING(Log::SPU, "sys_spu_thread_throw_event(spup=%d, data0=0x%x, data1=0x%x) failed (queue is full)", spup, (v & 0x00ffffff), data);
return; return;
@ -666,7 +666,7 @@ void SPUThread::WriteChannel(u32 ch, const u128& r)
return; return;
} }
u32 tid = GetCurrentCPUThread()->GetId(); const u32 tid = GetId();
ef->m_mutex.lock(tid); ef->m_mutex.lock(tid);
ef->flags |= (u64)1 << flag; ef->flags |= (u64)1 << flag;
@ -714,7 +714,7 @@ void SPUThread::WriteChannel(u32 ch, const u128& r)
return; return;
} }
u32 tid = GetCurrentCPUThread()->GetId(); const u32 tid = GetId();
ef->m_mutex.lock(tid); ef->m_mutex.lock(tid);
ef->flags |= (u64)1 << flag; ef->flags |= (u64)1 << flag;

View file

@ -593,8 +593,8 @@ void GLTexture::Save(RSXTexture& tex)
if (!rExists(dir_path)) rMkdir(dir_path); if (!rExists(dir_path)) rMkdir(dir_path);
u32 count = 0; u32 count = 0;
while (rExists(fmt::Format(file_fmt, count))) count++; while (rExists(fmt::Format(file_fmt.c_str(), count))) count++;
Save(tex, fmt::Format(file_fmt, count)); Save(tex, fmt::Format(file_fmt.c_str(), count));
} }
void GLTexture::Bind() void GLTexture::Bind()

View file

@ -436,7 +436,7 @@ std::string GLVertexDecompilerThread::BuildCode()
"%s\n" "%s\n"
"%s"; "%s";
return fmt::Format(prot, p.c_str(), fp.c_str(), f.c_str()); return fmt::Format(prot.c_str(), p.c_str(), fp.c_str(), f.c_str());
} }
void GLVertexDecompilerThread::Task() void GLVertexDecompilerThread::Task()
@ -648,7 +648,7 @@ void GLVertexProgram::Compile()
delete[] buf; delete[] buf;
} }
LOG_NOTICE(RSX, shader); LOG_NOTICE(RSX, "%s", shader.c_str());
Emu.Pause(); Emu.Pause();
} }
//else LOG_WARNING(RSX, "Vertex shader compiled successfully!"); //else LOG_WARNING(RSX, "Vertex shader compiled successfully!");

View file

@ -149,7 +149,7 @@ u32 RSXThread::OutOfArgsCount(const uint x, const u32 cmd, const u32 count, cons
debug += "("; debug += "(";
for(u32 i=0; i<count; ++i) debug += (i ? ", " : "") + fmt::Format("0x%x", ARGS(i)); for(u32 i=0; i<count; ++i) debug += (i ? ", " : "") + fmt::Format("0x%x", ARGS(i));
debug += ")"; debug += ")";
LOG_NOTICE(RSX, "OutOfArgsCount(x=%u, count=%u): " + debug, x, count); LOG_NOTICE(RSX, "OutOfArgsCount(x=%u, count=%u): %s", x, count, debug.c_str());
return 0; return 0;
} }
@ -2086,7 +2086,7 @@ void RSXThread::DoCmd(const u32 fcmd, const u32 cmd, const u32 args_addr, const
log += (i ? ", " : "") + fmt::Format("0x%x", ARGS(i)); log += (i ? ", " : "") + fmt::Format("0x%x", ARGS(i));
} }
log += ")"; log += ")";
LOG_ERROR(RSX, "TODO: " + log); LOG_ERROR(RSX, "TODO: %s", log.c_str());
} }
break; break;
} }

View file

@ -29,12 +29,12 @@ public:
virtual const std::string& GetName() const = 0; virtual const std::string& GetName() const = 0;
template<typename... Targs> void Notice(const u32 id, const char* fmt, Targs... args) const template<typename... Targs> __noinline void Notice(const u32 id, const char* fmt, Targs... args) const
{ {
LogOutput(LogNotice, id, ": ", fmt::Format(fmt, args...)); LogOutput(LogNotice, id, ": ", fmt::Format(fmt, args...));
} }
template<typename... Targs> void Notice(const char* fmt, Targs... args) const template<typename... Targs> __noinline void Notice(const char* fmt, Targs... args) const
{ {
LogOutput(LogNotice, ": ", fmt::Format(fmt, args...)); LogOutput(LogNotice, ": ", fmt::Format(fmt, args...));
} }
@ -55,42 +55,42 @@ public:
} }
} }
template<typename... Targs> void Success(const u32 id, const char* fmt, Targs... args) const template<typename... Targs> __noinline void Success(const u32 id, const char* fmt, Targs... args) const
{ {
LogOutput(LogSuccess, id, ": ", fmt::Format(fmt, args...)); LogOutput(LogSuccess, id, ": ", fmt::Format(fmt, args...));
} }
template<typename... Targs> void Success(const char* fmt, Targs... args) const template<typename... Targs> __noinline void Success(const char* fmt, Targs... args) const
{ {
LogOutput(LogSuccess, ": ", fmt::Format(fmt, args...)); LogOutput(LogSuccess, ": ", fmt::Format(fmt, args...));
} }
template<typename... Targs> void Warning(const u32 id, const char* fmt, Targs... args) const template<typename... Targs> __noinline void Warning(const u32 id, const char* fmt, Targs... args) const
{ {
LogOutput(LogWarning, id, " warning: ", fmt::Format(fmt, args...)); LogOutput(LogWarning, id, " warning: ", fmt::Format(fmt, args...));
} }
template<typename... Targs> void Warning(const char* fmt, Targs... args) const template<typename... Targs> __noinline void Warning(const char* fmt, Targs... args) const
{ {
LogOutput(LogWarning, " warning: ", fmt::Format(fmt, args...)); LogOutput(LogWarning, " warning: ", fmt::Format(fmt, args...));
} }
template<typename... Targs> void Error(const u32 id, const char* fmt, Targs... args) const template<typename... Targs> __noinline void Error(const u32 id, const char* fmt, Targs... args) const
{ {
LogOutput(LogError, id, " error: ", fmt::Format(fmt, args...)); LogOutput(LogError, id, " error: ", fmt::Format(fmt, args...));
} }
template<typename... Targs> void Error(const char* fmt, Targs... args) const template<typename... Targs> __noinline void Error(const char* fmt, Targs... args) const
{ {
LogOutput(LogError, " error: ", fmt::Format(fmt, args...)); LogOutput(LogError, " error: ", fmt::Format(fmt, args...));
} }
template<typename... Targs> void Todo(const u32 id, const char* fmt, Targs... args) const template<typename... Targs> __noinline void Todo(const u32 id, const char* fmt, Targs... args) const
{ {
LogOutput(LogError, id, " TODO: ", fmt::Format(fmt, args...)); LogOutput(LogError, id, " TODO: ", fmt::Format(fmt, args...));
} }
template<typename... Targs> void Todo(const char* fmt, Targs... args) const template<typename... Targs> __noinline void Todo(const char* fmt, Targs... args) const
{ {
LogOutput(LogError, " TODO: ", fmt::Format(fmt, args...)); LogOutput(LogError, " TODO: ", fmt::Format(fmt, args...));
} }

View file

@ -224,7 +224,7 @@ bool ModuleManager::IsLoadedFunc(u32 id) const
return false; return false;
} }
bool ModuleManager::CallFunc(u32 num) bool ModuleManager::CallFunc(PPUThread& CPU, u32 num)
{ {
func_caller* func = nullptr; func_caller* func = nullptr;
{ {
@ -242,7 +242,7 @@ bool ModuleManager::CallFunc(u32 num)
if (func) if (func)
{ {
(*func)(); (*func)(CPU);
return true; return true;
} }
return false; return false;

View file

@ -18,7 +18,7 @@ public:
void AddFunc(ModuleFunc *func); void AddFunc(ModuleFunc *func);
void SetModule(u16 id, Module* module);//insert into m_modules void SetModule(u16 id, Module* module);//insert into m_modules
bool IsLoadedFunc(u32 id) const; bool IsLoadedFunc(u32 id) const;
bool CallFunc(u32 num); bool CallFunc(PPUThread& CPU, u32 num);
bool UnloadFunc(u32 id); bool UnloadFunc(u32 id);
void UnloadModules(); void UnloadModules();
u32 GetFuncNumById(u32 id); u32 GetFuncNumById(u32 id);

View file

@ -187,7 +187,6 @@ int cellGameContentPermit(vm::ptr<char[CELL_GAME_PATH_MAX]> contentInfoPath, vm:
return CELL_GAME_ERROR_FAILURE; return CELL_GAME_ERROR_FAILURE;
} }
// TODO: make it better
strcpy_trunc(*contentInfoPath, contentInfo); strcpy_trunc(*contentInfoPath, contentInfo);
strcpy_trunc(*usrdirPath, usrdir); strcpy_trunc(*usrdirPath, usrdir);

View file

@ -529,8 +529,7 @@ int cellSurMixerStart()
int cellSurMixerSetParameter(u32 param, float value) int cellSurMixerSetParameter(u32 param, float value)
{ {
declCPU(); libmixer->Todo("cellSurMixerSetParameter(param=0x%x, value=%f)", param, value);
libmixer->Todo("cellSurMixerSetParameter(param=0x%x, value=%f, FPR[1]=%f, FPR[2]=%f)", param, value, (float&)CPU.FPR[1], (float&)CPU.FPR[2]);
return CELL_OK; return CELL_OK;
} }
@ -616,28 +615,25 @@ void cellSurMixerBeep(u32 arg)
return; return;
} }
void cellSurMixerUtilGetLevelFromDB(float dB) float cellSurMixerUtilGetLevelFromDB(float dB)
{ {
// not hooked, probably unnecessary // not hooked, probably unnecessary
libmixer->Todo("cellSurMixerUtilGetLevelFromDB(dB=%f)", dB); libmixer->Todo("cellSurMixerUtilGetLevelFromDB(dB=%f)", dB);
declCPU(); return 0.0f;
(float&)CPU.FPR[0] = 0.0f;
} }
void cellSurMixerUtilGetLevelFromDBIndex(int index) float cellSurMixerUtilGetLevelFromDBIndex(s32 index)
{ {
// not hooked, probably unnecessary // not hooked, probably unnecessary
libmixer->Todo("cellSurMixerUtilGetLevelFromDBIndex(index=%d)", index); libmixer->Todo("cellSurMixerUtilGetLevelFromDBIndex(index=%d)", index);
declCPU(); return 0.0f;
(float&)CPU.FPR[0] = 0.0f;
} }
void cellSurMixerUtilNoteToRatio(u8 refNote, u8 note) float cellSurMixerUtilNoteToRatio(u8 refNote, u8 note)
{ {
// not hooked, probably unnecessary // not hooked, probably unnecessary
libmixer->Todo("cellSurMixerUtilNoteToRatio(refNote=%d, note=%d)", refNote, note); libmixer->Todo("cellSurMixerUtilNoteToRatio(refNote=%d, note=%d)", refNote, note);
declCPU(); return 0.0f;
(float&)CPU.FPR[0] = 0.0f;
} }
void libmixer_init(Module *pxThis) void libmixer_init(Module *pxThis)

View file

@ -4,7 +4,7 @@
class func_caller class func_caller
{ {
public: public:
virtual void operator()() = 0; virtual void operator()(PPUThread& CPU) = 0;
virtual ~func_caller(){}; virtual ~func_caller(){};
}; };
@ -169,13 +169,31 @@ namespace detail
{ {
} }
virtual void operator()() virtual void operator()(PPUThread& CPU)
{ {
declCPU();
call<void>(m_call, iterate<0, 0, 0, T...>(CPU)); call<void>(m_call, iterate<0, 0, 0, T...>(CPU));
} }
}; };
template<typename... T>
class func_binder<void, PPUThread&, T...> : public func_caller
{
typedef void(*func_t)(PPUThread&, T...);
const func_t m_call;
public:
func_binder(func_t call)
: func_caller()
, m_call(call)
{
}
virtual void operator()(PPUThread& CPU)
{
call<void>(m_call, std::tuple_cat(std::tuple<PPUThread&>(CPU), iterate<0, 0, 0, T...>(CPU)));
}
};
template<typename RT, typename... T> template<typename RT, typename... T>
class func_binder : public func_caller class func_binder : public func_caller
{ {
@ -189,9 +207,8 @@ namespace detail
{ {
} }
virtual void operator()() virtual void operator()(PPUThread& CPU)
{ {
declCPU();
static_assert(!std::is_pointer<RT>::value, "Invalid function result type (pointer)"); static_assert(!std::is_pointer<RT>::value, "Invalid function result type (pointer)");
static_assert(!std::is_reference<RT>::value, "Invalid function result type (reference)"); static_assert(!std::is_reference<RT>::value, "Invalid function result type (reference)");
const bool is_float = std::is_floating_point<RT>::value; const bool is_float = std::is_floating_point<RT>::value;
@ -201,6 +218,31 @@ namespace detail
bind_result<RT, t>::func(CPU, call<RT>(m_call, iterate<0, 0, 0, T...>(CPU))); bind_result<RT, t>::func(CPU, call<RT>(m_call, iterate<0, 0, 0, T...>(CPU)));
} }
}; };
template<typename RT, typename... T>
class func_binder<RT, PPUThread&, T...> : public func_caller
{
typedef RT(*func_t)(PPUThread&, T...);
const func_t m_call;
public:
func_binder(func_t call)
: func_caller()
, m_call(call)
{
}
virtual void operator()(PPUThread& CPU)
{
static_assert(!std::is_pointer<RT>::value, "Invalid function result type (pointer)");
static_assert(!std::is_reference<RT>::value, "Invalid function result type (reference)");
const bool is_float = std::is_floating_point<RT>::value;
const bool is_vector = std::is_same<RT, u128>::value;
const bind_arg_type t = is_float ? ARG_FLOAT : (is_vector ? ARG_VECTOR : ARG_GENERAL);
bind_result<RT, t>::func(CPU, call<RT>(m_call, std::tuple_cat(std::tuple<PPUThread&>(CPU), iterate<0, 0, 0, T...>(CPU))));
}
};
} }
template<typename RT, typename... T> template<typename RT, typename... T>

View file

@ -179,11 +179,11 @@ void StaticFuncManager::StaticAnalyse(void* ptr, u32 size, u32 base)
} }
} }
void StaticFuncManager::StaticExecute(u32 code) void StaticFuncManager::StaticExecute(PPUThread& CPU, u32 code)
{ {
if (code < m_static_funcs_list.size()) if (code < m_static_funcs_list.size())
{ {
(*m_static_funcs_list[code]->func)(); (*m_static_funcs_list[code]->func)(CPU);
} }
else else
{ {

View file

@ -2,12 +2,14 @@
struct SFunc; struct SFunc;
class PPUThread;
class StaticFuncManager class StaticFuncManager
{ {
std::vector<SFunc *> m_static_funcs_list; std::vector<SFunc *> m_static_funcs_list;
public: public:
void StaticAnalyse(void* ptr, u32 size, u32 base); void StaticAnalyse(void* ptr, u32 size, u32 base);
void StaticExecute(u32 code); void StaticExecute(PPUThread& CPU, u32 code);
void StaticFinalize(); void StaticFinalize();
void push_back(SFunc *ele); void push_back(SFunc *ele);
SFunc *operator[](size_t i); SFunc *operator[](size_t i);

View file

@ -11,8 +11,6 @@
#include "lv2/sys_event.h" #include "lv2/sys_event.h"
#include "lv2/sys_event_flag.h" #include "lv2/sys_event_flag.h"
#include "lv2/sys_interrupt.h" #include "lv2/sys_interrupt.h"
//#include "lv2/sys_lwcond.h"
//#include "lv2/sys_lwmutex.h"
#include "lv2/sys_memory.h" #include "lv2/sys_memory.h"
#include "lv2/sys_mmapper.h" #include "lv2/sys_mmapper.h"
#include "lv2/sys_ppu_thread.h" #include "lv2/sys_ppu_thread.h"
@ -37,7 +35,7 @@ namespace detail{
} }
} }
void default_syscall(); void default_syscall(PPUThread& CPU);
static func_caller *null_func = bind_func(default_syscall); static func_caller *null_func = bind_func(default_syscall);
static const int kSyscallTableLength = 1024; static const int kSyscallTableLength = 1024;
@ -62,7 +60,7 @@ static func_caller* sc_table[kSyscallTableLength] =
bind_func(sys_process_get_number_of_object), //12 (0x00C) bind_func(sys_process_get_number_of_object), //12 (0x00C)
bind_func(sys_process_get_id), //13 (0x00D) bind_func(sys_process_get_id), //13 (0x00D)
null_func,//bind_func(sys_process_is_spu_lock_line_reservation_address), //14 (0x00E) bind_func(sys_process_is_spu_lock_line_reservation_address), //14 (0x00E)
null_func, null_func, null_func, //15-17 UNS null_func, null_func, null_func, //15-17 UNS
@ -153,12 +151,12 @@ static func_caller* sc_table[kSyscallTableLength] =
bind_func(sys_cond_signal), //108 (0x06C) bind_func(sys_cond_signal), //108 (0x06C)
bind_func(sys_cond_signal_all), //109 (0x06D) bind_func(sys_cond_signal_all), //109 (0x06D)
bind_func(sys_cond_signal_to), //110 (0x06E) bind_func(sys_cond_signal_to), //110 (0x06E)
null_func,//bind_func(sys_lwcond_create) //111 (0x06F) null_func,//bind_func(sys_lwcond_create) //111 (0x06F) // internal, used by sys_lwcond_create
null_func,//bind_func(sys_lwcond_destroy) //112 (0x070) null_func,//bind_func(sys_lwcond_destroy) //112 (0x070) // internal, used by sys_lwcond_destroy
null_func,//bind_func(sys_lwcond_queue_wait) //113 (0x071) null_func,//bind_func(sys_lwcond_queue_wait) //113 (0x071) // internal, used by sys_lwcond_wait
bind_func(sys_semaphore_get_value), //114 (0x072) bind_func(sys_semaphore_get_value), //114 (0x072)
null_func,//bind_func(sys_semaphore_...) //115 (0x073) null_func,//bind_func(sys_semaphore_...) //115 (0x073) // internal, used by sys_lwcond_signal, sys_lwcond_signal_to
null_func,//bind_func(sys_semaphore_...) //116 (0x074) null_func,//bind_func(sys_semaphore_...) //116 (0x074) // internal, used by sys_lwcond_signal_all
null_func,//bind_func(sys_semaphore_...) //117 (0x075) // internal, used by sys_lwmutex_unlock null_func,//bind_func(sys_semaphore_...) //117 (0x075) // internal, used by sys_lwmutex_unlock
bind_func(sys_event_flag_clear), //118 (0x076) bind_func(sys_event_flag_clear), //118 (0x076)
null_func,//bind_func(sys_event_...) //119 (0x077) ROOT null_func,//bind_func(sys_event_...) //119 (0x077) ROOT
@ -912,9 +910,8 @@ struct SyscallTableCleaner_t
} }
} SyscallTableCleaner_t; } SyscallTableCleaner_t;
void default_syscall() void default_syscall(PPUThread& CPU)
{ {
declCPU();
u32 code = (u32)CPU.GPR[11]; u32 code = (u32)CPU.GPR[11];
//TODO: remove this //TODO: remove this
switch(code) switch(code)
@ -943,25 +940,24 @@ void default_syscall()
return; return;
} }
void SysCalls::DoSyscall(u32 code) void SysCalls::DoSyscall(PPUThread& CPU, u32 code)
{ {
//Auto Pause using simple singleton. //Auto Pause using simple singleton.
Debug::AutoPause::getInstance().TryPause(code); Debug::AutoPause::getInstance().TryPause(code);
if(code < 1024) if(code < 1024)
{ {
(*sc_table[code])(); (*sc_table[code])(CPU);
return; return;
} }
if(Emu.GetModuleManager().CallFunc(code)) if(Emu.GetModuleManager().CallFunc(CPU, code))
{ {
return; return;
} }
LOG_ERROR(HLE, "TODO: %s", GetHLEFuncName(code).c_str()); LOG_ERROR(HLE, "TODO: %s", GetHLEFuncName(code).c_str());
declCPU();
CPU.GPR[3] = 0; CPU.GPR[3] = 0;
} }

View file

@ -60,9 +60,11 @@ public:
extern bool dump_enable; extern bool dump_enable;
class PPUThread;
class SysCalls class SysCalls
{ {
public: public:
static void DoSyscall(u32 code); static void DoSyscall(PPUThread& CPU, u32 code);
static std::string GetHLEFuncName(const u32 fid); static std::string GetHLEFuncName(const u32 fid);
}; };

View file

@ -103,7 +103,7 @@ s32 sys_cond_signal_all(u32 cond_id)
while (u32 target = (mutex->protocol == SYS_SYNC_PRIORITY ? cond->m_queue.pop_prio() : cond->m_queue.pop())) while (u32 target = (mutex->protocol == SYS_SYNC_PRIORITY ? cond->m_queue.pop_prio() : cond->m_queue.pop()))
{ {
cond->signaler = GetCurrentCPUThread()->GetId(); cond->signaler = GetCurrentPPUThread().GetId();
//cond->signal_stamp = get_system_time(); //cond->signal_stamp = get_system_time();
cond->signal.lock(target); cond->signal.lock(target);
Emu.GetCPU().NotifyThread(target); Emu.GetCPU().NotifyThread(target);

View file

@ -1,13 +1,22 @@
#pragma once #pragma once
#define SYS_MEMORY_CONTAINER_ID_INVALID 0xFFFFFFFF enum : u32
#define SYS_MEMORY_ACCESS_RIGHT_NONE 0x00000000000000F0ULL {
#define SYS_MEMORY_ACCESS_RIGHT_PPU_THREAD 0x0000000000000008ULL SYS_MEMORY_CONTAINER_ID_INVALID = 0xFFFFFFFF,
#define SYS_MEMORY_ACCESS_RIGHT_HANDLER 0x0000000000000004ULL };
#define SYS_MEMORY_ACCESS_RIGHT_SPU_THREAD 0x0000000000000002ULL
#define SYS_MEMORY_ACCESS_RIGHT_SPU_RAW 0x0000000000000001ULL enum : u64
#define SYS_MEMORY_ATTR_READ_ONLY 0x0000000000080000ULL {
#define SYS_MEMORY_ATTR_READ_WRITE 0x0000000000040000ULL SYS_MEMORY_ACCESS_RIGHT_NONE = 0x00000000000000F0ULL,
SYS_MEMORY_ACCESS_RIGHT_ANY = 0x000000000000000FULL,
SYS_MEMORY_ACCESS_RIGHT_PPU_THR = 0x0000000000000008ULL,
SYS_MEMORY_ACCESS_RIGHT_HANDLER = 0x0000000000000004ULL,
SYS_MEMORY_ACCESS_RIGHT_SPU_THR = 0x0000000000000002ULL,
SYS_MEMORY_ACCESS_RIGHT_RAW_SPU = 0x0000000000000001ULL,
SYS_MEMORY_ATTR_READ_ONLY = 0x0000000000080000ULL,
SYS_MEMORY_ATTR_READ_WRITE = 0x0000000000040000ULL,
};
enum enum
{ {

View file

@ -2,6 +2,7 @@
#include "Emu/Memory/Memory.h" #include "Emu/Memory/Memory.h"
#include "Emu/System.h" #include "Emu/System.h"
#include "Emu/SysCalls/SysCalls.h" #include "Emu/SysCalls/SysCalls.h"
#include "Emu/SysCalls/Callback.h"
#include "Emu/CPU/CPUThreadManager.h" #include "Emu/CPU/CPUThreadManager.h"
#include "Emu/Cell/PPUThread.h" #include "Emu/Cell/PPUThread.h"
@ -11,33 +12,30 @@ static SysCallBase sys_ppu_thread("sys_ppu_thread");
static const u32 PPU_THREAD_ID_INVALID = 0xFFFFFFFFU/*UUUUUUUUUUuuuuuuuuuu~~~~~~~~*/; static const u32 PPU_THREAD_ID_INVALID = 0xFFFFFFFFU/*UUUUUUUUUUuuuuuuuuuu~~~~~~~~*/;
void ppu_thread_exit(u64 errorcode) void ppu_thread_exit(PPUThread& CPU, u64 errorcode)
{ {
PPUThread& thr = GetCurrentPPUThread(); if (CPU.owned_mutexes)
u32 tid = thr.GetId();
if (thr.owned_mutexes)
{ {
sys_ppu_thread.Error("Owned mutexes found (%d)", thr.owned_mutexes); sys_ppu_thread.Error("Owned mutexes found (%d)", CPU.owned_mutexes);
thr.owned_mutexes = 0; CPU.owned_mutexes = 0;
} }
thr.SetExitStatus(errorcode); CPU.SetExitStatus(errorcode);
thr.Stop(); CPU.Stop();
} }
void sys_ppu_thread_exit(u64 errorcode) void sys_ppu_thread_exit(PPUThread& CPU, u64 errorcode)
{ {
sys_ppu_thread.Log("sys_ppu_thread_exit(0x%llx)", errorcode); sys_ppu_thread.Log("sys_ppu_thread_exit(0x%llx)", errorcode);
ppu_thread_exit(errorcode); ppu_thread_exit(CPU, errorcode);
} }
void sys_internal_ppu_thread_exit(u64 errorcode) void sys_internal_ppu_thread_exit(PPUThread& CPU, u64 errorcode)
{ {
sys_ppu_thread.Log("sys_internal_ppu_thread_exit(0x%llx)", errorcode); sys_ppu_thread.Log("sys_internal_ppu_thread_exit(0x%llx)", errorcode);
ppu_thread_exit(errorcode); ppu_thread_exit(CPU, errorcode);
} }
s32 sys_ppu_thread_yield() s32 sys_ppu_thread_yield()
@ -83,10 +81,11 @@ s32 sys_ppu_thread_detach(u64 thread_id)
return CELL_OK; return CELL_OK;
} }
void sys_ppu_thread_get_join_state(u32 isjoinable_addr) void sys_ppu_thread_get_join_state(PPUThread& CPU, vm::ptr<s32> isjoinable)
{ {
sys_ppu_thread.Warning("sys_ppu_thread_get_join_state(isjoinable_addr=0x%x)", isjoinable_addr); sys_ppu_thread.Warning("sys_ppu_thread_get_join_state(isjoinable_addr=0x%x)", isjoinable.addr());
vm::write32(isjoinable_addr, GetCurrentPPUThread().IsJoinable());
*isjoinable = CPU.IsJoinable();
} }
s32 sys_ppu_thread_set_priority(u64 thread_id, s32 prio) s32 sys_ppu_thread_set_priority(u64 thread_id, s32 prio)
@ -113,12 +112,10 @@ s32 sys_ppu_thread_get_priority(u64 thread_id, u32 prio_addr)
return CELL_OK; return CELL_OK;
} }
s32 sys_ppu_thread_get_stack_information(u32 info_addr) s32 sys_ppu_thread_get_stack_information(PPUThread& CPU, u32 info_addr)
{ {
sys_ppu_thread.Log("sys_ppu_thread_get_stack_information(info_addr=0x%x)", info_addr); sys_ppu_thread.Log("sys_ppu_thread_get_stack_information(info_addr=0x%x)", info_addr);
declCPU();
vm::write32(info_addr, (u32)CPU.GetStackAddr()); vm::write32(info_addr, (u32)CPU.GetStackAddr());
vm::write32(info_addr + 4, CPU.GetStackSize()); vm::write32(info_addr + 4, CPU.GetStackSize());
@ -203,22 +200,22 @@ s32 sys_ppu_thread_create(vm::ptr<be_t<u64>> thread_id, u32 entry, u64 arg, s32
return CELL_OK; return CELL_OK;
} }
void sys_ppu_thread_once(vm::ptr<std::atomic<be_t<u32>>> once_ctrl, u32 entry) void sys_ppu_thread_once(PPUThread& CPU, vm::ptr<std::atomic<be_t<u32>>> once_ctrl, vm::ptr<void(*)()> init)
{ {
sys_ppu_thread.Warning("sys_ppu_thread_once(once_ctrl_addr=0x%x, entry=0x%x)", once_ctrl.addr(), entry); sys_ppu_thread.Warning("sys_ppu_thread_once(once_ctrl_addr=0x%x, init_addr=0x%x)", once_ctrl.addr(), init.addr());
be_t<u32> old = be_t<u32>::MakeFromBE(se32(SYS_PPU_THREAD_ONCE_INIT)); be_t<u32> old = be_t<u32>::MakeFromBE(se32(SYS_PPU_THREAD_ONCE_INIT));
if (once_ctrl->compare_exchange_weak(old, be_t<u32>::MakeFromBE(se32(SYS_PPU_THREAD_DONE_INIT)))) if (once_ctrl->compare_exchange_weak(old, be_t<u32>::MakeFromBE(se32(SYS_PPU_THREAD_DONE_INIT))))
{ {
GetCurrentPPUThread().FastCall2(vm::read32(entry), vm::read32(entry + 4)); init.call(CPU);
} }
} }
s32 sys_ppu_thread_get_id(vm::ptr<be_t<u64>> thread_id) s32 sys_ppu_thread_get_id(PPUThread& CPU, vm::ptr<be_t<u64>> thread_id)
{ {
sys_ppu_thread.Log("sys_ppu_thread_get_id(thread_id_addr=0x%x)", thread_id.addr()); sys_ppu_thread.Log("sys_ppu_thread_get_id(thread_id_addr=0x%x)", thread_id.addr());
*thread_id = GetCurrentPPUThread().GetId(); *thread_id = CPU.GetId();
return CELL_OK; return CELL_OK;
} }

View file

@ -13,18 +13,18 @@ enum ppu_thread_flags : u64
}; };
// SysCalls // SysCalls
void sys_ppu_thread_exit(u64 errorcode); void sys_ppu_thread_exit(PPUThread& CPU, u64 errorcode);
void sys_internal_ppu_thread_exit(u64 errorcode); void sys_internal_ppu_thread_exit(PPUThread& CPU, u64 errorcode);
s32 sys_ppu_thread_yield(); s32 sys_ppu_thread_yield();
s32 sys_ppu_thread_join(u64 thread_id, vm::ptr<be_t<u64>> vptr); s32 sys_ppu_thread_join(u64 thread_id, vm::ptr<be_t<u64>> vptr);
s32 sys_ppu_thread_detach(u64 thread_id); s32 sys_ppu_thread_detach(u64 thread_id);
void sys_ppu_thread_get_join_state(u32 isjoinable_addr); void sys_ppu_thread_get_join_state(PPUThread& CPU, vm::ptr<s32> isjoinable);
s32 sys_ppu_thread_set_priority(u64 thread_id, s32 prio); s32 sys_ppu_thread_set_priority(u64 thread_id, s32 prio);
s32 sys_ppu_thread_get_priority(u64 thread_id, u32 prio_addr); s32 sys_ppu_thread_get_priority(u64 thread_id, u32 prio_addr);
s32 sys_ppu_thread_get_stack_information(u32 info_addr); s32 sys_ppu_thread_get_stack_information(PPUThread& CPU, u32 info_addr);
s32 sys_ppu_thread_stop(u64 thread_id); s32 sys_ppu_thread_stop(u64 thread_id);
s32 sys_ppu_thread_restart(u64 thread_id); s32 sys_ppu_thread_restart(u64 thread_id);
s32 sys_ppu_thread_create(vm::ptr<be_t<u64>> thread_id, u32 entry, u64 arg, s32 prio, u32 stacksize, u64 flags, vm::ptr<const char> threadname); s32 sys_ppu_thread_create(vm::ptr<be_t<u64>> thread_id, u32 entry, u64 arg, s32 prio, u32 stacksize, u64 flags, vm::ptr<const char> threadname);
void sys_ppu_thread_once(vm::ptr<std::atomic<be_t<u32>>> once_ctrl, u32 entry); void sys_ppu_thread_once(PPUThread& CPU, vm::ptr<std::atomic<be_t<u32>>> once_ctrl, vm::ptr<void(*)()> init);
s32 sys_ppu_thread_get_id(vm::ptr<be_t<u64>> thread_id); s32 sys_ppu_thread_get_id(PPUThread& CPU, vm::ptr<be_t<u64>> thread_id);
s32 sys_ppu_thread_rename(u64 thread_id, vm::ptr<const char> name); s32 sys_ppu_thread_rename(u64 thread_id, vm::ptr<const char> name);

View file

@ -3,6 +3,7 @@
#include "Emu/System.h" #include "Emu/System.h"
#include "Emu/SysCalls/SysCalls.h" #include "Emu/SysCalls/SysCalls.h"
#include "sys_memory.h"
#include "sys_process.h" #include "sys_process.h"
SysCallBase sys_process("sys_process"); SysCallBase sys_process("sys_process");
@ -212,6 +213,24 @@ s32 sys_process_get_id(u32 object, vm::ptr<be_t<u32>> buffer, u32 size, vm::ptr<
return CELL_OK; return CELL_OK;
} }
s32 process_is_spu_lock_line_reservation_address(u32 addr, u64 flags)
{
if (!flags || flags & ~(SYS_MEMORY_ACCESS_RIGHT_SPU_THR | SYS_MEMORY_ACCESS_RIGHT_RAW_SPU))
{
return CELL_EINVAL;
}
// TODO
return CELL_OK;
}
s32 sys_process_is_spu_lock_line_reservation_address(u32 addr, u64 flags)
{
sys_process.Warning("sys_process_is_spu_lock_line_reservation_address(addr=0x%x, flags=0x%llx)", addr, flags);
return process_is_spu_lock_line_reservation_address(addr, flags);
}
s32 sys_process_get_paramsfo(vm::ptr<u8> buffer) s32 sys_process_get_paramsfo(vm::ptr<u8> buffer)
{ {
sys_process.Todo("sys_process_get_paramsfo(buffer_addr=0x%x) -> CELL_ENOENT", buffer.addr()); sys_process.Todo("sys_process_get_paramsfo(buffer_addr=0x%x) -> CELL_ENOENT", buffer.addr());

View file

@ -26,6 +26,7 @@ enum
// Auxiliary functions // Auxiliary functions
s32 process_getpid(); s32 process_getpid();
s32 process_get_sdk_version(u32 pid, s32& ver); s32 process_get_sdk_version(u32 pid, s32& ver);
s32 process_is_spu_lock_line_reservation_address(u32 addr, u64 flags);
// SysCalls // SysCalls
s32 sys_process_getpid(); s32 sys_process_getpid();
@ -35,6 +36,7 @@ s32 sys_process_get_id(u32 object, vm::ptr<be_t<u32>> buffer, u32 size, vm::ptr<
s32 sys_process_get_paramsfo(vm::ptr<u8> buffer); s32 sys_process_get_paramsfo(vm::ptr<u8> buffer);
s32 sys_process_get_sdk_version(u32 pid, vm::ptr<be_t<s32>> version); s32 sys_process_get_sdk_version(u32 pid, vm::ptr<be_t<s32>> version);
s32 sys_process_get_status(u64 unk); s32 sys_process_get_status(u64 unk);
s32 sys_process_is_spu_lock_line_reservation_address(u32 addr, u64 flags);
s32 sys_process_exit(s32 errorcode); s32 sys_process_exit(s32 errorcode);
s32 sys_process_kill(u32 pid); s32 sys_process_kill(u32 pid);
s32 sys_process_wait_for_child(u32 pid, vm::ptr<be_t<u32>> status, u64 unk); s32 sys_process_wait_for_child(u32 pid, vm::ptr<be_t<u32>> status, u64 unk);

View file

@ -269,7 +269,7 @@ void Emulator::Load()
} }
catch(const std::string& e) catch(const std::string& e)
{ {
LOG_ERROR(LOADER, e); LOG_ERROR(LOADER, "%s", e.c_str());
is_error = true; is_error = true;
} }
catch(...) catch(...)

View file

@ -251,9 +251,9 @@ void VHDDExplorer::OnCreateDir(wxCommandEvent& event)
{ {
int i = 1; int i = 1;
static const std::string& fmt = "New Dir (%d)"; static const std::string& fmt = "New Dir (%d)";
while(m_hdd->HasEntry(fmt::Format(fmt, i))) i++; while(m_hdd->HasEntry(fmt::Format(fmt.c_str(), i))) i++;
m_hdd->Create(vfsHDD_Entry_Dir, fmt::Format(fmt, i)); m_hdd->Create(vfsHDD_Entry_Dir, fmt::Format(fmt.c_str(), i));
UpdateList(); UpdateList();
} }
@ -261,9 +261,9 @@ void VHDDExplorer::OnCreateFile(wxCommandEvent& event)
{ {
int i = 1; int i = 1;
static const std::string& fmt = "New File (%d)"; static const std::string& fmt = "New File (%d)";
while (m_hdd->HasEntry(fmt::Format(fmt, i))) i++; while (m_hdd->HasEntry(fmt::Format(fmt.c_str(), i))) i++;
m_hdd->Create(vfsHDD_Entry_File, fmt::Format(fmt, i)); m_hdd->Create(vfsHDD_Entry_File, fmt::Format(fmt.c_str(), i));
UpdateList(); UpdateList();
} }