#pragma once #include #include #include #include namespace Util { struct Error { enum Severity { NONE, WARN, ERROR, FATAL, }; union MemoryAccess { struct { unsigned : 3; unsigned is_write : 1; unsigned is_fatal : 1; unsigned size : 3; }; u8 raw; }; enum Type { SCHEDULER_EOL, SCHEDULER_UNKNOWN, UNHANDLED_EXCEPTION, UNHANDLED_INSTRUCTION, INVALID_INSTRUCTION_FORMAT, TLB_LIMIT_EXCEEDED, TLB_INVALID_ERROR, TLB_UNHANDLED_ERROR, TLB_UNHANDLED_MAPPING, JIT_BRANCH_INSIDE_DELAY_SLOT, JIT_INVALID_X86_REG_ADDRESSING, COULD_NOT_SYNC_SAVE_DATA, SAVE_DATA_IS_CORRUPT_OR_INVALID_SIZE, MMAP_MAKE_SINK_ERROR, MEM_INVALID_ACCESS, MEM_UNHANDLED_ACCESS, RDP_LIMIT_EXCEEDED, FLASH_EXECUTE_COMMAND_ERROR, PIF_UNHANDLED_CHANNEL, UNHANDLED_COP0_STATUS_BIT, COP0_INVALID_ACCESS, COP0_UNHANDLED_ACCESS, SYSTEM_DIALOG_ERROR, TAS_LOAD_ERROR, ROM_LOAD_ERROR, SAVE_OPTIONS_ERROR, }; template void Throw (Severity severity, Type type, std::optional lastPC, std::optional memoryAccess, const std::format_string fmt, Args... args) { this->severity = severity; this->lastPC = lastPC; this->memoryAccess = memoryAccess; this->type = type; return std::format(fmt, std::forward(args)...); } void SetHandled() { severity = NONE; } bool IsHandled() { return severity == NONE; } static Error& GetInstance() { static Error instance; return instance; } static std::string Get() { return GetInstance().err; } private: std::string err; Severity severity = NONE; Type type = {}; std::optional lastPC = {}; std::optional memoryAccess = {}; }; }