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

View file

@ -2,49 +2,28 @@
#include "OpenAL/include/al.h" #include "OpenAL/include/al.h"
#include "OpenAL/include/alc.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 class OpenALThread
{ {
private: private:
ALuint mSource; static const uint g_al_buffers_count = 16;
SampleBuffer mBuffers;
SampleInfo mBuffer; ALuint m_source;
ALint mProcessed; ALuint m_buffers[g_al_buffers_count];
u16 mTempBuffer[512]; ALCdevice* m_device;
ALCcontext* m_context;
u32 m_buffer_size;
public: public:
~OpenALThread();
void Init(); void Init();
void Quit(); void Quit();
void Play(); void Play();
void Open(const void* src, ALsizei size); void Open(const void* src, ALsizei size);
void Close(); void Close();
void Stop(); 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); void AddData(const void* src, ALsizei size);
}; };

View file

@ -1606,6 +1606,10 @@ private:
{ {
DisAsm_V1_R2("lvlx", vd, ra, rb); 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) void LWBRX(u32 rd, u32 ra, u32 rb)
{ {
DisAsm_R3("lwbrx", rd, ra, 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); /*0x1e9*/bind_instr(g1f_list, DIVD, RD, RA, RB, OE, RC);
/*0x1eb*/bind_instr(g1f_list, DIVW, 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); /*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); /*0x216*/bind_instr(g1f_list, LWBRX, RD, RA, RB);
/*0x217*/bind_instr(g1f_list, LFSX, FRD, RA, RB); /*0x217*/bind_instr(g1f_list, LFSX, FRD, RA, RB);
/*0x218*/bind_instr(g1f_list, SRW, RA, RS, RB, RC); /*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); 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) void LWBRX(u32 rd, u32 ra, u32 rb)
{ {
CPU.GPR[rd] = (u32&)Memory[ra ? CPU.GPR[ra] + CPU.GPR[rb] : CPU.GPR[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) 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) void FMSUB(u32 frd, u32 fra, u32 frc, u32 frb, bool rc)
{ {

View file

@ -340,6 +340,7 @@ namespace PPU_opcodes
DIVD = 0x1e9, DIVD = 0x1e9,
DIVW = 0x1eb, DIVW = 0x1eb,
LVLX = 0x207, //Load Vector Left Indexed LVLX = 0x207, //Load Vector Left Indexed
LDBRX = 0x214,
LWBRX = 0x216, LWBRX = 0x216,
LFSX = 0x217, LFSX = 0x217,
SRW = 0x218, SRW = 0x218,
@ -729,6 +730,7 @@ public:
virtual void DIVD(u32 rd, u32 ra, u32 rb, u32 oe, bool rc) = 0; 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 DIVW(u32 rd, u32 ra, u32 rb, u32 oe, bool rc) = 0;
virtual void LVLX(u32 vd, u32 ra, u32 rb) = 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 LWBRX(u32 rd, u32 ra, u32 rb) = 0;
virtual void LFSX(u32 frd, 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; 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; 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; std::string cond;
if(!src0.exec_if_gr || !src0.exec_if_lt || !src0.exec_if_eq) 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"; 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"; 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) for(u32 i=0; i<m_parr.params.GetCount(); ++i)
{ {

View file

@ -319,7 +319,8 @@ wxString GLVertexDecompilerThread::BuildCode()
wxString f = wxEmptyString; 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) for(uint i=1; i<m_funcs.GetCount(); ++i)
{ {
@ -354,6 +355,11 @@ void GLVertexDecompilerThread::Task()
src[2].src2l = d3.src2l; src[2].src2l = d3.src2l;
src[2].src2h = d2.src2h; src[2].src2h = d2.src2h;
if(!d1.sca_opcode && !d1.vec_opcode)
{
m_body.Add("//nop");
}
switch(d1.sca_opcode) switch(d1.sca_opcode)
{ {
case 0x00: break; // NOP case 0x00: break; // NOP
@ -364,11 +370,11 @@ void GLVertexDecompilerThread::Task()
case 0x05: AddScaCode("exp(" + GetSRC(2, true) + ")"); break; // EXP case 0x05: AddScaCode("exp(" + GetSRC(2, true) + ")"); break; // EXP
case 0x06: AddScaCode("log(" + GetSRC(2, true) + ")"); break; // LOG case 0x06: AddScaCode("log(" + GetSRC(2, true) + ")"); break; // LOG
//case 0x07: break; // LIT //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 0x08: AddScaCode("{ /*BRA*/ " + GetFunc() + "; 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 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 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 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 0x0d: AddScaCode("log2(" + GetSRC(2, true) + ")"); break; // LG2
case 0x0e: AddScaCode("exp2(" + GetSRC(2, true) + ")"); break; // EX2 case 0x0e: AddScaCode("exp2(" + GetSRC(2, true) + ")"); break; // EX2
case 0x0f: AddScaCode("sin(" + GetSRC(2, true) + ")"); break; // SIN case 0x0f: AddScaCode("sin(" + GetSRC(2, true) + ")"); break; // SIN
@ -429,7 +435,7 @@ void GLVertexDecompilerThread::Task()
m_shader = BuildCode(); m_shader = BuildCode();
m_body.Clear(); m_body.Clear();
m_funcs.RemoveAt(1, m_funcs.GetCount() - 1); m_funcs.RemoveAt(2, m_funcs.GetCount() - 2);
} }
GLVertexProgram::GLVertexProgram() GLVertexProgram::GLVertexProgram()

View file

@ -151,6 +151,9 @@ struct GLVertexDecompilerThread : public ThreadBase
m_funcs.Add(new FuncInfo()); m_funcs.Add(new FuncInfo());
m_funcs[0].offset = 0; m_funcs[0].offset = 0;
m_funcs[0].name = "main"; 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"; //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: case adecDecodeAu:
{ {
int err;
adec.reader.addr = task.au.addr; adec.reader.addr = task.au.addr;
adec.reader.size = task.au.size; adec.reader.size = task.au.size;

View file

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

View file

@ -45,8 +45,8 @@ AboutDialog::AboutDialog(wxWindow *parent)
//Credits //Credits
wxBoxSizer* s_panel_credits(new wxBoxSizer(wxHORIZONTAL)); 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_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", 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->AddSpacer(12);
s_panel_credits->Add(t_section1); 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 max_item_count = 500;
static const uint buffer_size = 1024 * 64; static const uint buffer_size = 1024 * 64;
static const std::string g_log_colors[] =
{
"Black", "Green", "White", "Yellow", "Red",
};
struct LogPacket struct LogPacket
{ {
std::string m_prefix; 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()) if(!prefix.empty())
{ {
@ -125,7 +130,8 @@ void LogWriter::WriteToLog(std::string prefix, std::string value, std::string co
if(m_logfile.IsOpened()) if(m_logfile.IsOpened())
m_logfile.Write(wxString(prefix.empty() ? "" : std::string("[" + prefix + "]: ") + value + "\n").wx_str()); 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); 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(); //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, ...) void LogWriter::Write(const wxString fmt, ...)
@ -169,7 +175,7 @@ void LogWriter::Write(const wxString fmt, ...)
va_end(list); va_end(list);
WriteToLog("!", (const char *)frmt.ToAscii(), "White"); WriteToLog("!", (const char *)frmt.ToAscii(), 2);
} }
void LogWriter::Error(const wxString fmt, ...) void LogWriter::Error(const wxString fmt, ...)
@ -182,7 +188,7 @@ void LogWriter::Error(const wxString fmt, ...)
va_end(list); 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, ...) void LogWriter::Warning(const wxString fmt, ...)
@ -195,7 +201,7 @@ void LogWriter::Warning(const wxString fmt, ...)
va_end(list); 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, ...) void LogWriter::Success(const wxString fmt, ...)
@ -208,12 +214,12 @@ void LogWriter::Success(const wxString fmt, ...)
va_end(list); va_end(list);
WriteToLog("S", static_cast<const char *>(frmt), "Green"); WriteToLog("S", static_cast<const char *>(frmt), 1);
} }
void LogWriter::SkipLn() void LogWriter::SkipLn()
{ {
WriteToLog("", "", "Black"); WriteToLog("", "", 0);
} }
BEGIN_EVENT_TABLE(LogFrame, wxPanel) BEGIN_EVENT_TABLE(LogFrame, wxPanel)

View file

@ -11,7 +11,7 @@ class LogWriter
std::string m_prefix; std::string m_prefix;
std::string m_value; 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: public:
LogWriter(); 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_audio_out( new wxStaticBoxSizer( wxVERTICAL, &diag, _("Audio Out") ) );
wxStaticBoxSizer* s_round_hle( new wxStaticBoxSizer( wxVERTICAL, &diag, _("HLE / Misc.") ) ); 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_cpu_decoder = new wxComboBox(&diag, wxID_ANY);
wxComboBox* cbox_gs_render = 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_keyboard_handler = new wxComboBox(&diag, wxID_ANY);
wxComboBox* cbox_mouse_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_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_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"); 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("Null");
cbox_audio_out->Append("OpenAL"); 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_cpu_ignore_rwerrors->SetValue(Ini.CPUIgnoreRWErrors.GetValue());
chbox_gs_log_prog->SetValue(Ini.GSLogPrograms.GetValue()); chbox_gs_log_prog->SetValue(Ini.GSLogPrograms.GetValue());
chbox_gs_dump_depth->SetValue(Ini.GSDumpDepthBuffer.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_hle_exitonstop->SetValue(Ini.HLEExitOnStop.GetValue());
chbox_audio_dump->Enable(Emu.IsStopped()); chbox_audio_dump->Enable(Emu.IsStopped());
cbox_audio_out->Enable(Emu.IsStopped());
chbox_hle_logging->Enable(Emu.IsStopped()); chbox_hle_logging->Enable(Emu.IsStopped());
cbox_cpu_decoder->SetSelection(Ini.CPUDecoderMode.GetValue() ? Ini.CPUDecoderMode.GetValue() - 1 : 0); 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_keyboard_handler->SetSelection(Ini.KeyboardHandlerMode.GetValue());
cbox_mouse_handler->SetSelection(Ini.MouseHandlerMode.GetValue()); cbox_mouse_handler->SetSelection(Ini.MouseHandlerMode.GetValue());
cbox_audio_out->SetSelection(Ini.AudioOutMode.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_decoder->Add(cbox_cpu_decoder, wxSizerFlags().Border(wxALL, 5).Expand());
s_round_cpu->Add(s_round_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_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_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_logging, wxSizerFlags().Border(wxALL, 5).Expand());
s_round_hle->Add(chbox_hle_savetty, 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()); 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.HLELogging.SetValue(chbox_hle_logging->GetValue());
Ini.HLESaveTTY.SetValue(chbox_hle_savetty->GetValue()); Ini.HLESaveTTY.SetValue(chbox_hle_savetty->GetValue());
Ini.HLEExitOnStop.SetValue(chbox_hle_exitonstop->GetValue()); Ini.HLEExitOnStop.SetValue(chbox_hle_exitonstop->GetValue());
Ini.HLELogLvl.SetValue(cbox_hle_loglvl->GetSelection());
Ini.Save(); Ini.Save();
} }

View file

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