Improved OpenAL audio output

Implemented LDBRX PPU instruction
Enabled FRSQRTE PPU instruction
Improved Fragment Program Decompiler
Implemented Log lvl selection
This commit is contained in:
DH 2014-03-13 02:26:53 +02:00
parent 80cfb2eb58
commit 0e437312ad
16 changed files with 167 additions and 138 deletions

View File

@ -4,8 +4,8 @@
ALenum g_last_al_error = AL_NO_ERROR;
ALCenum g_last_alc_error = ALC_NO_ERROR;
ALCdevice* pDevice;
ALCcontext* pContext;
#define checkForAlError(sit) if((g_last_al_error = alGetError()) != AL_NO_ERROR) printAlError(g_last_al_error, sit)
#define checkForAlcError(sit) if((g_last_alc_error = alcGetError(m_device)) != ALC_NO_ERROR) printAlcError(g_last_alc_error, sit)
void printAlError(ALenum err, const char* situation)
{
@ -25,120 +25,124 @@ void printAlcError(ALCenum err, const char* situation)
}
}
OpenALThread::~OpenALThread()
{
Quit();
}
void OpenALThread::Init()
{
pDevice = alcOpenDevice(NULL);
m_device = alcOpenDevice(nullptr);
checkForAlcError("alcOpenDevice");
pContext = alcCreateContext(pDevice, NULL);
m_context = alcCreateContext(m_device, nullptr);
checkForAlcError("alcCreateContext");
alcMakeContextCurrent(pContext);
alcMakeContextCurrent(m_context);
checkForAlcError("alcMakeContextCurrent");
}
void OpenALThread::Quit()
{
for (SampleBuffer::iterator i = mBuffers.begin(); i != mBuffers.end(); i++)
alDeleteBuffers(1, &i->second.mBufferID);
alcMakeContextCurrent(NULL);
alcDestroyContext(pContext);
alcCloseDevice(pDevice);
alcMakeContextCurrent(nullptr);
alcDestroyContext(m_context);
alcCloseDevice(m_device);
}
void OpenALThread::Play()
{
alSourcePlay(mSource);
checkForAlError("alSourcePlay");
ALint state;
alGetSourcei(m_source, AL_SOURCE_STATE, &state);
checkForAlError("alGetSourcei");
if(state != AL_PLAYING)
{
alSourcePlay(m_source);
checkForAlError("alSourcePlay");
}
}
void OpenALThread::Close()
{
alSourceStop(mSource);
alSourceStop(m_source);
checkForAlError("alSourceStop");
if (alIsSource(mSource))
alDeleteSources(1, &mSource);
if (alIsSource(m_source))
alDeleteSources(1, &m_source);
alDeleteBuffers(g_al_buffers_count, m_buffers);
checkForAlError("alDeleteBuffers");
}
void OpenALThread::Stop()
{
alSourceStop(mSource);
alSourceStop(m_source);
checkForAlError("alSourceStop");
}
void OpenALThread::Open(const void* src, ALsizei size)
{
alGenSources(1, &mSource);
alGenSources(1, &m_source);
checkForAlError("alGenSources");
alSourcei(mSource, AL_LOOPING, AL_FALSE);
alGenBuffers(g_al_buffers_count, m_buffers);
checkForAlError("alGenBuffers");
alSourcei(m_source, AL_LOOPING, AL_FALSE);
checkForAlError("alSourcei");
mProcessed = 0;
mBuffer.mFreq = 48000;
mBuffer.mFormat = AL_FORMAT_STEREO16;
m_buffer_size = size;
for (int i = 0; i < NUM_OF_BUFFERS; i++)
for(uint i=0; i<g_al_buffers_count; ++i)
{
AddData(src, size);
AddBlock(m_buffers[i], m_buffer_size, src);
}
alSourceQueueBuffers(m_source, g_al_buffers_count, m_buffers);
checkForAlError("alSourceQueueBuffers");
Play();
}
void OpenALThread::AddData(const void* src, ALsizei size)
{
alGenBuffers(1, &mBuffer.mBufferID);
checkForAlError("alGenBuffers");
mBuffers[mBuffer.mBufferID] = mBuffer;
AddBlock(mBuffer.mBufferID, size, src);
const char* bsrc = (const char*)src;
ALuint buffer;
ALint buffers_count;
alGetSourcei(m_source, AL_BUFFERS_PROCESSED, &buffers_count);
checkForAlError("alGetSourcei");
alSourceQueueBuffers(mSource, 1, &mBuffer.mBufferID);
checkForAlError("alSourceQueueBuffers");
alGetSourcei(mSource, AL_BUFFERS_PROCESSED, &mProcessed);
while (mProcessed--)
while(size)
{
alSourceUnqueueBuffers(mSource, 1, &mBuffer.mBufferID);
if(buffers_count-- <= 0)
{
Play();
alGetSourcei(m_source, AL_BUFFERS_PROCESSED, &buffers_count);
checkForAlError("alGetSourcei");
continue;
}
alSourceUnqueueBuffers(m_source, 1, &buffer);
checkForAlError("alSourceUnqueueBuffers");
alDeleteBuffers(1, &mBuffer.mBufferID);
checkForAlError("alDeleteBuffers");
int bsize = size < m_buffer_size ? size : m_buffer_size;
AddBlock(buffer, bsize, bsrc);
alSourceQueueBuffers(m_source, 1, &buffer);
checkForAlError("alSourceQueueBuffers");
size -= bsize;
bsrc += bsize;
}
Play();
}
bool OpenALThread::AddBlock(ALuint bufferID, ALsizei size, const void* src)
bool OpenALThread::AddBlock(const ALuint buffer_id, ALsizei size, const void* src)
{
memset(&mTempBuffer, 0, sizeof(mTempBuffer));
memcpy(mTempBuffer, src, size);
long TotalRet = 0, ret;
if (size < 1) return false;
while (TotalRet < size)
{
ret = size;
// if buffer is empty
if (ret == 0) break;
else if (ret < 0)
{
ConLog.Error("Error in bitstream!");
}
else
{
TotalRet += ret;
}
}
if (TotalRet > 0)
{
alBufferData(bufferID, mBuffers[bufferID].mFormat, mTempBuffer,
TotalRet, mBuffers[bufferID].mFreq);
alBufferData(buffer_id, AL_FORMAT_STEREO16, src, size, 48000);
checkForAlError("alBufferData");
}
return (ret > 0);
return true;
}

View File

@ -2,49 +2,28 @@
#include "OpenAL/include/al.h"
#include "OpenAL/include/alc.h"
#include <map>
extern ALenum g_last_al_error;
extern ALCenum g_last_alc_error;
void printAlError(ALenum err, const char* situation);
void printAlcError(ALCenum err, const char* situation);
#define checkForAlError(sit) if((g_last_al_error = alGetError()) != AL_NO_ERROR) printAlError(g_last_al_error, sit)
#define checkForAlcError(sit) if((g_last_alc_error = alcGetError(pDevice)) != ALC_NO_ERROR) printAlcError(g_last_alc_error, sit)
struct SampleInfo
{
uint mBufferID;
uint mFreq;
uint mFormat;
};
typedef std::map<ALuint, SampleInfo> SampleBuffer;
#define NUM_OF_BUFFERS 16
extern ALCdevice* pDevice;
extern ALCcontext* pContext;
class OpenALThread
{
private:
ALuint mSource;
SampleBuffer mBuffers;
SampleInfo mBuffer;
ALint mProcessed;
u16 mTempBuffer[512];
static const uint g_al_buffers_count = 16;
ALuint m_source;
ALuint m_buffers[g_al_buffers_count];
ALCdevice* m_device;
ALCcontext* m_context;
u32 m_buffer_size;
public:
~OpenALThread();
void Init();
void Quit();
void Play();
void Open(const void* src, ALsizei size);
void Close();
void Stop();
bool AddBlock(ALuint bufferID, ALsizei size, const void* src);
bool AddBlock(const ALuint buffer_id, ALsizei size, const void* src);
void AddData(const void* src, ALsizei size);
};

View File

@ -1606,6 +1606,10 @@ private:
{
DisAsm_V1_R2("lvlx", vd, ra, rb);
}
void LDBRX(u32 rd, u32 ra, u32 rb)
{
DisAsm_R3("ldbrx", rd, ra, rb);
}
void LWBRX(u32 rd, u32 ra, u32 rb)
{
DisAsm_R3("lwbrx", rd, ra, rb);

View File

@ -527,6 +527,7 @@ namespace PPU_instr
/*0x1e9*/bind_instr(g1f_list, DIVD, RD, RA, RB, OE, RC);
/*0x1eb*/bind_instr(g1f_list, DIVW, RD, RA, RB, OE, RC);
/*0x207*/bind_instr(g1f_list, LVLX, VD, RA, RB);
/*0x214*/bind_instr(g1f_list, LDBRX, RD, RA, RB);
/*0x216*/bind_instr(g1f_list, LWBRX, RD, RA, RB);
/*0x217*/bind_instr(g1f_list, LFSX, FRD, RA, RB);
/*0x218*/bind_instr(g1f_list, SRW, RA, RS, RB, RC);

View File

@ -2981,6 +2981,10 @@ private:
Memory.ReadLeft(CPU.VPR[vd]._u8 + eb, addr, 16 - eb);
}
void LDBRX(u32 rd, u32 ra, u32 rb)
{
CPU.GPR[rd] = (u64&)Memory[ra ? CPU.GPR[ra] + CPU.GPR[rb] : CPU.GPR[rb]];
}
void LWBRX(u32 rd, u32 ra, u32 rb)
{
CPU.GPR[rd] = (u32&)Memory[ra ? CPU.GPR[ra] + CPU.GPR[rb] : CPU.GPR[rb]];
@ -3758,8 +3762,7 @@ private:
}
void FRSQRTE(u32 frd, u32 frb, bool rc)
{
UNIMPLEMENTED();
//CPU.FPR[frd] = 1.0f / (float)sqrt(CPU.FPR[frb]);
CPU.FPR[frd] = 1.0f / (float)sqrt(CPU.FPR[frb]);
}
void FMSUB(u32 frd, u32 fra, u32 frc, u32 frb, bool rc)
{

View File

@ -340,6 +340,7 @@ namespace PPU_opcodes
DIVD = 0x1e9,
DIVW = 0x1eb,
LVLX = 0x207, //Load Vector Left Indexed
LDBRX = 0x214,
LWBRX = 0x216,
LFSX = 0x217,
SRW = 0x218,
@ -729,6 +730,7 @@ public:
virtual void DIVD(u32 rd, u32 ra, u32 rb, u32 oe, bool rc) = 0;
virtual void DIVW(u32 rd, u32 ra, u32 rb, u32 oe, bool rc) = 0;
virtual void LVLX(u32 vd, u32 ra, u32 rb) = 0;
virtual void LDBRX(u32 rd, u32 ra, u32 rb) = 0;
virtual void LWBRX(u32 rd, u32 ra, u32 rb) = 0;
virtual void LFSX(u32 frd, u32 ra, u32 rb) = 0;
virtual void SRW(u32 ra, u32 rs, u32 rb, bool rc) = 0;

View File

@ -5,7 +5,7 @@ void GLFragmentDecompilerThread::AddCode(std::string code, bool append_mask)
{
if(!src0.exec_if_eq && !src0.exec_if_gr && !src0.exec_if_lt) return;
const std::string mask = GetMask().c_str();
const std::string mask = GetMask();
std::string cond;
if(!src0.exec_if_gr || !src0.exec_if_lt || !src0.exec_if_eq)
@ -227,7 +227,7 @@ std::string GLFragmentDecompilerThread::BuildCode()
main += "\t" + m_parr.AddParam(PARAM_OUT, "vec4", "ocol", 0) + " = " + (m_ctrl & 0x40 ? "r0" : "h0") + ";\n";
if(m_ctrl & 0xe) main += "\tgl_FragDepth = r1.z;\n";
std::string p = "";
std::string p;
for(u32 i=0; i<m_parr.params.GetCount(); ++i)
{

View File

@ -319,7 +319,8 @@ wxString GLVertexDecompilerThread::BuildCode()
wxString f = wxEmptyString;
f += wxString::Format("void %s()\n{\n\tgl_Position = vec4(0.0f, 0.0f, 0.0f, 1.0f);\n%s\tgl_Position = gl_Position * scaleOffsetMat;\n}\n", m_funcs[0].name.wx_str(), BuildFuncBody(m_funcs[0]).wx_str());
f += wxString::Format("void %s()\n{\n\tgl_Position = vec4(0.0f, 0.0f, 0.0f, 1.0f);\n\t%s();\n\tgl_Position = gl_Position * scaleOffsetMat;\n}\n",
m_funcs[0].name.wx_str(), m_funcs[1].name.wx_str());
for(uint i=1; i<m_funcs.GetCount(); ++i)
{
@ -354,6 +355,11 @@ void GLVertexDecompilerThread::Task()
src[2].src2l = d3.src2l;
src[2].src2h = d2.src2h;
if(!d1.sca_opcode && !d1.vec_opcode)
{
m_body.Add("//nop");
}
switch(d1.sca_opcode)
{
case 0x00: break; // NOP
@ -364,11 +370,11 @@ void GLVertexDecompilerThread::Task()
case 0x05: AddScaCode("exp(" + GetSRC(2, true) + ")"); break; // EXP
case 0x06: AddScaCode("log(" + GetSRC(2, true) + ")"); break; // LOG
//case 0x07: break; // LIT
case 0x08: AddScaCode("{ /*BRA*/ " + GetFunc() + "; " + wxString(m_funcs.GetCount() == 1 || m_funcs[1].offset > intsCount ? "gl_Position = gl_Position * scaleOffsetMat;" : "") + " return; }", false, true); break; // BRA
case 0x09: AddScaCode("{ " + GetFunc() + "; " + wxString(m_funcs.GetCount() == 1 || m_funcs[1].offset > intsCount ? "gl_Position = gl_Position * scaleOffsetMat;" : "") + " return; }", false, true); break; // BRI : works differently (BRI o[1].x(TR) L0;)
case 0x08: AddScaCode("{ /*BRA*/ " + GetFunc() + "; return; }", false, true); break; // BRA
case 0x09: AddScaCode("{ " + GetFunc() + "; return; }", false, true); break; // BRI : works differently (BRI o[1].x(TR) L0;)
case 0x0a: AddScaCode("/*CAL*/ " + GetFunc(), false, true); break; // CAL : works same as BRI
case 0x0b: AddScaCode("/*CLI*/ " + GetFunc(), false, true); break; // CLI : works same as BRI
case 0x0c: AddScaCode("{ " + wxString(m_funcs.GetCount() == 1 || m_funcs[1].offset > intsCount ? "gl_Position = gl_Position * scaleOffsetMat;" : "") + "return; }", false, true); break; // RET : works like BRI but shorter (RET o[1].x(TR);)
case 0x0c: AddScaCode("return", false, true); break; // RET : works like BRI but shorter (RET o[1].x(TR);)
case 0x0d: AddScaCode("log2(" + GetSRC(2, true) + ")"); break; // LG2
case 0x0e: AddScaCode("exp2(" + GetSRC(2, true) + ")"); break; // EX2
case 0x0f: AddScaCode("sin(" + GetSRC(2, true) + ")"); break; // SIN
@ -429,7 +435,7 @@ void GLVertexDecompilerThread::Task()
m_shader = BuildCode();
m_body.Clear();
m_funcs.RemoveAt(1, m_funcs.GetCount() - 1);
m_funcs.RemoveAt(2, m_funcs.GetCount() - 2);
}
GLVertexProgram::GLVertexProgram()

View File

@ -151,6 +151,9 @@ struct GLVertexDecompilerThread : public ThreadBase
m_funcs.Add(new FuncInfo());
m_funcs[0].offset = 0;
m_funcs[0].name = "main";
m_funcs.Add(new FuncInfo());
m_funcs[1].offset = 0;
m_funcs[1].name = "func0";
//m_cur_func->body = "\tgl_Position = vec4(0.0f, 0.0f, 0.0f, 1.0f);\n";
}

View File

@ -119,8 +119,6 @@ u32 adecOpen(AudioDecoder* data)
case adecDecodeAu:
{
int err;
adec.reader.addr = task.au.addr;
adec.reader.size = task.au.size;

View File

@ -17,9 +17,6 @@ int cellAudioInit()
{
cellAudio.Warning("cellAudioInit()");
if(Ini.AudioOutMode.GetValue() == 1)
m_audio_out->Init();
if (m_config.m_is_audio_initialized)
{
return CELL_AUDIO_ERROR_ALREADY_INIT;
@ -53,14 +50,21 @@ int cellAudioInit()
float buffer[2*256]; // buffer for 2 channels
be_t<float> buffer2[8*256]; // buffer for 8 channels (max count)
u16 oal_buffer[2*256]; // buffer for OpenAL
//u16 oal_buffer[2*256]; // buffer for OpenAL
memset(&buffer, 0, sizeof(buffer));
memset(&buffer2, 0, sizeof(buffer2));
memset(&oal_buffer, 0, sizeof(oal_buffer));
uint oal_buffer_offset = 0;
uint oal_buffer_size = 2 * 256;
std::unique_ptr<u16[]> oal_buffer(new u16[oal_buffer_size]);
memset(buffer, 0, sizeof(buffer));
memset(buffer2, 0, sizeof(buffer2));
memset(oal_buffer.get(), 0, oal_buffer_size * sizeof(u16));
if(Ini.AudioOutMode.GetValue() == 1)
m_audio_out->Open(oal_buffer, sizeof(oal_buffer));
{
m_audio_out->Init();
m_audio_out->Open(oal_buffer.get(), oal_buffer_size*sizeof(u16));
}
while (m_config.m_is_audio_initialized)
{
@ -120,8 +124,10 @@ int cellAudioInit()
buffer[i] = buffer2[i];
// convert the data from float to u16
oal_buffer[i] = (u16)((float)buffer[i] * (1 << 15));
assert(buffer[i] >= -4.0f && buffer[i] <= 4.0f);
oal_buffer[oal_buffer_offset + i] = (u16)(buffer[i] * ((1 << 13) - 1));
}
first_mix = false;
}
else
@ -131,7 +137,8 @@ int cellAudioInit()
buffer[i] = (buffer[i] + buffer2[i]) * 0.5; // TODO: valid mixing
// convert the data from float to u16
oal_buffer[i] = (u16)((float)buffer[i] * (1 << 15));
assert(buffer[i] >= -4.0f && buffer[i] <= 4.0f);
oal_buffer[oal_buffer_offset + i] = (u16)(buffer[i] * ((1 << 13) - 1));
}
}
}
@ -140,8 +147,14 @@ int cellAudioInit()
// TODO: check event source
Emu.GetEventManager().SendEvent(m_config.event_key, 0x10103000e010e07, 0, 0, 0);
if(Ini.AudioOutMode.GetValue() == 1)
m_audio_out->AddData(oal_buffer, sizeof(oal_buffer));
oal_buffer_offset += sizeof(buffer) / sizeof(float);
if(oal_buffer_offset >= oal_buffer_size)
{
m_audio_out->AddData(oal_buffer.get(), oal_buffer_offset * sizeof(u16));
oal_buffer_offset = 0;
}
if(Ini.AudioDumpToFile.GetValue())
{
@ -160,8 +173,6 @@ abort:
m_dump.Finalize();
m_config.m_is_audio_finalized = true;
if(Ini.AudioOutMode.GetValue() == 1)
m_audio_out->Quit();
});
t.detach();
@ -191,8 +202,6 @@ int cellAudioQuit()
Memory.Free(m_config.m_buffer);
Memory.Free(m_config.m_indexes);
if(Ini.AudioOutMode.GetValue() == 1)
m_audio_out->Quit();
return CELL_OK;
}
@ -301,9 +310,6 @@ int cellAudioPortStart(u32 portNum)
m_config.m_ports[portNum].m_is_audio_port_started = true;
if(Ini.AudioOutMode.GetValue() == 1)
m_audio_out->Play();
return CELL_OK;
}

View File

@ -45,8 +45,8 @@ AboutDialog::AboutDialog(wxWindow *parent)
//Credits
wxBoxSizer* s_panel_credits(new wxBoxSizer(wxHORIZONTAL));
wxStaticText* t_section1 = new wxStaticText(this, wxID_ANY, "\nDevelopers:\n\nDH\nAlexAltea\nHykem\nOil", wxDefaultPosition, wxSize(156,160));
wxStaticText* t_section2 = new wxStaticText(this, wxID_ANY, "\nThanks:\n\nBlackDaemon", wxDefaultPosition, wxSize(156,160));
wxStaticText* t_section1 = new wxStaticText(this, wxID_ANY, "\nDevelopers:\n\nDH\nAlexAltea\nHykem\nOil\nNekotekina\nelisha464\nBigpet", wxDefaultPosition, wxSize(156,160));
wxStaticText* t_section2 = new wxStaticText(this, wxID_ANY, "\nThanks:\n\nBlackDaemon\nAishou\nkrofna\nxsacha", wxDefaultPosition, wxSize(156,160));
s_panel_credits->AddSpacer(12);
s_panel_credits->Add(t_section1);

View File

@ -14,6 +14,11 @@ std::mutex g_cs_conlog;
static const uint max_item_count = 500;
static const uint buffer_size = 1024 * 64;
static const std::string g_log_colors[] =
{
"Black", "Green", "White", "Yellow", "Red",
};
struct LogPacket
{
std::string m_prefix;
@ -112,7 +117,7 @@ LogWriter::LogWriter()
}
}
void LogWriter::WriteToLog(std::string prefix, std::string value, std::string colour/*, wxColour bgcolour*/)
void LogWriter::WriteToLog(std::string prefix, std::string value, u8 lvl/*, wxColour bgcolour*/)
{
if(!prefix.empty())
{
@ -125,7 +130,8 @@ void LogWriter::WriteToLog(std::string prefix, std::string value, std::string co
if(m_logfile.IsOpened())
m_logfile.Write(wxString(prefix.empty() ? "" : std::string("[" + prefix + "]: ") + value + "\n").wx_str());
if(!ConLogFrame) return;
if(!ConLogFrame || Ini.HLELogLvl.GetValue() == 4 || (lvl != 0 && lvl <= Ini.HLELogLvl.GetValue()))
return;
std::lock_guard<std::mutex> lock(g_cs_conlog);
@ -156,7 +162,7 @@ void LogWriter::WriteToLog(std::string prefix, std::string value, std::string co
//if(LogBuffer.put == LogBuffer.get) LogBuffer.Flush();
LogBuffer.Push(LogPacket(prefix, value, colour));
LogBuffer.Push(LogPacket(prefix, value, g_log_colors[lvl]));
}
void LogWriter::Write(const wxString fmt, ...)
@ -169,7 +175,7 @@ void LogWriter::Write(const wxString fmt, ...)
va_end(list);
WriteToLog("!", (const char *)frmt.ToAscii(), "White");
WriteToLog("!", (const char *)frmt.ToAscii(), 2);
}
void LogWriter::Error(const wxString fmt, ...)
@ -182,7 +188,7 @@ void LogWriter::Error(const wxString fmt, ...)
va_end(list);
WriteToLog("E", static_cast<const char *>(frmt), "Red");
WriteToLog("E", static_cast<const char *>(frmt), 4);
}
void LogWriter::Warning(const wxString fmt, ...)
@ -195,7 +201,7 @@ void LogWriter::Warning(const wxString fmt, ...)
va_end(list);
WriteToLog("W", static_cast<const char *>(frmt), "Yellow");
WriteToLog("W", static_cast<const char *>(frmt), 3);
}
void LogWriter::Success(const wxString fmt, ...)
@ -208,12 +214,12 @@ void LogWriter::Success(const wxString fmt, ...)
va_end(list);
WriteToLog("S", static_cast<const char *>(frmt), "Green");
WriteToLog("S", static_cast<const char *>(frmt), 1);
}
void LogWriter::SkipLn()
{
WriteToLog("", "", "Black");
WriteToLog("", "", 0);
}
BEGIN_EVENT_TABLE(LogFrame, wxPanel)

View File

@ -11,7 +11,7 @@ class LogWriter
std::string m_prefix;
std::string m_value;
virtual void WriteToLog(std::string prefix, std::string value, std::string colour);
virtual void WriteToLog(std::string prefix, std::string value, u8 lvl);
public:
LogWriter();

View File

@ -346,6 +346,7 @@ void MainFrame::Config(wxCommandEvent& WXUNUSED(event))
wxStaticBoxSizer* s_round_audio_out( new wxStaticBoxSizer( wxVERTICAL, &diag, _("Audio Out") ) );
wxStaticBoxSizer* s_round_hle( new wxStaticBoxSizer( wxVERTICAL, &diag, _("HLE / Misc.") ) );
wxStaticBoxSizer* s_round_hle_log_lvl( new wxStaticBoxSizer( wxVERTICAL, &diag, _("Log lvl") ) );
wxComboBox* cbox_cpu_decoder = new wxComboBox(&diag, wxID_ANY);
wxComboBox* cbox_gs_render = new wxComboBox(&diag, wxID_ANY);
@ -355,6 +356,7 @@ void MainFrame::Config(wxCommandEvent& WXUNUSED(event))
wxComboBox* cbox_keyboard_handler = new wxComboBox(&diag, wxID_ANY);
wxComboBox* cbox_mouse_handler = new wxComboBox(&diag, wxID_ANY);
wxComboBox* cbox_audio_out = new wxComboBox(&diag, wxID_ANY);
wxComboBox* cbox_hle_loglvl = new wxComboBox(&diag, wxID_ANY);
wxCheckBox* chbox_cpu_ignore_rwerrors = new wxCheckBox(&diag, wxID_ANY, "Ignore Read/Write errors");
wxCheckBox* chbox_gs_log_prog = new wxCheckBox(&diag, wxID_ANY, "Log vertex/fragment programs");
@ -397,6 +399,12 @@ void MainFrame::Config(wxCommandEvent& WXUNUSED(event))
cbox_audio_out->Append("Null");
cbox_audio_out->Append("OpenAL");
cbox_hle_loglvl->Append("All");
cbox_hle_loglvl->Append("Success");
cbox_hle_loglvl->Append("Warnings");
cbox_hle_loglvl->Append("Errors");
cbox_hle_loglvl->Append("Nothing");
chbox_cpu_ignore_rwerrors->SetValue(Ini.CPUIgnoreRWErrors.GetValue());
chbox_gs_log_prog->SetValue(Ini.GSLogPrograms.GetValue());
chbox_gs_dump_depth->SetValue(Ini.GSDumpDepthBuffer.GetValue());
@ -408,6 +416,7 @@ void MainFrame::Config(wxCommandEvent& WXUNUSED(event))
chbox_hle_exitonstop->SetValue(Ini.HLEExitOnStop.GetValue());
chbox_audio_dump->Enable(Emu.IsStopped());
cbox_audio_out->Enable(Emu.IsStopped());
chbox_hle_logging->Enable(Emu.IsStopped());
cbox_cpu_decoder->SetSelection(Ini.CPUDecoderMode.GetValue() ? Ini.CPUDecoderMode.GetValue() - 1 : 0);
@ -418,6 +427,7 @@ void MainFrame::Config(wxCommandEvent& WXUNUSED(event))
cbox_keyboard_handler->SetSelection(Ini.KeyboardHandlerMode.GetValue());
cbox_mouse_handler->SetSelection(Ini.MouseHandlerMode.GetValue());
cbox_audio_out->SetSelection(Ini.AudioOutMode.GetValue());
cbox_hle_loglvl->SetSelection(Ini.HLELogLvl.GetValue());
s_round_cpu_decoder->Add(cbox_cpu_decoder, wxSizerFlags().Border(wxALL, 5).Expand());
s_round_cpu->Add(s_round_cpu_decoder, wxSizerFlags().Border(wxALL, 5).Expand());
@ -445,6 +455,8 @@ void MainFrame::Config(wxCommandEvent& WXUNUSED(event))
s_round_audio_out->Add(chbox_audio_dump, wxSizerFlags().Border(wxALL, 5).Expand());
s_round_audio->Add(s_round_audio_out, wxSizerFlags().Border(wxALL, 5).Expand());
s_round_hle_log_lvl->Add(cbox_hle_loglvl, wxSizerFlags().Border(wxALL, 5).Expand());
s_round_hle->Add(s_round_hle_log_lvl, wxSizerFlags().Border(wxALL, 5).Expand());
s_round_hle->Add(chbox_hle_logging, wxSizerFlags().Border(wxALL, 5).Expand());
s_round_hle->Add(chbox_hle_savetty, wxSizerFlags().Border(wxALL, 5).Expand());
s_round_hle->Add(chbox_hle_exitonstop, wxSizerFlags().Border(wxALL, 5).Expand());
@ -487,6 +499,7 @@ void MainFrame::Config(wxCommandEvent& WXUNUSED(event))
Ini.HLELogging.SetValue(chbox_hle_logging->GetValue());
Ini.HLESaveTTY.SetValue(chbox_hle_savetty->GetValue());
Ini.HLEExitOnStop.SetValue(chbox_hle_exitonstop->GetValue());
Ini.HLELogLvl.SetValue(cbox_hle_loglvl->GetSelection());
Ini.Save();
}

View File

@ -109,6 +109,7 @@ public:
IniEntry<bool> HLELogging;
IniEntry<bool> HLESaveTTY;
IniEntry<bool> HLEExitOnStop;
IniEntry<u8> HLELogLvl;
IniEntry<int> PadHandlerLeft;
IniEntry<int> PadHandlerDown;
@ -176,6 +177,7 @@ public:
HLELogging.Init("HLELogging", path);
HLESaveTTY.Init("HLESaveTTY", path);
HLEExitOnStop.Init("HLEExitOnStop", path);
HLELogLvl.Init("HLELogLvl", path);
}
void Load()
@ -197,6 +199,7 @@ public:
HLELogging.Load(false);
HLESaveTTY.Load(false);
HLEExitOnStop.Load(false);
HLELogLvl.Load(0);
PadHandlerLeft.Load(static_cast<int>('A'));
PadHandlerDown.Load(static_cast<int>('S'));
@ -235,6 +238,7 @@ public:
HLELogging.Save();
HLESaveTTY.Save();
HLEExitOnStop.Save();
HLELogLvl.Save();
PadHandlerLeft.Save();
PadHandlerDown.Save();