mirror of
https://github.com/RPCS3/rpcs3.git
synced 2024-12-27 15:26:19 +00:00
Improved OpenGL renderer.
- Improved Vertex Shader Decompiler. - Fixed CMD analyzer. - Improved sys_fs module. - Minor fixes.
This commit is contained in:
parent
dd48f827c3
commit
8259006bc3
@ -35,7 +35,7 @@ public:
|
||||
switch(sizeof(T))
|
||||
{
|
||||
case 1:
|
||||
res = m_data;
|
||||
(u8&)res = (u8&)m_data;
|
||||
break;
|
||||
|
||||
case 2:
|
||||
@ -68,7 +68,7 @@ public:
|
||||
switch(sizeof(T))
|
||||
{
|
||||
case 1:
|
||||
m_data = value;
|
||||
(u8&)m_data = (u8&)value;
|
||||
return;
|
||||
|
||||
case 2:
|
||||
|
@ -170,7 +170,7 @@ void VFS::SaveLoadDevices(Array<VFSManagerEntry>& res, bool is_load)
|
||||
res[idx].path = "$(EmulatorDir)\\dev_hdd0\\";
|
||||
res[idx].mount = "/dev_hdd0/";
|
||||
res[idx].device = vfsDevice_LocalFile;
|
||||
|
||||
/*
|
||||
idx = res.Move(new VFSManagerEntry());
|
||||
res[idx].path = "$(GameDir)";
|
||||
res[idx].mount = "";
|
||||
@ -180,6 +180,7 @@ void VFS::SaveLoadDevices(Array<VFSManagerEntry>& res, bool is_load)
|
||||
res[idx].path = "$(GameDir)";
|
||||
res[idx].mount = "/";
|
||||
res[idx].device = vfsDevice_LocalFile;
|
||||
*/
|
||||
|
||||
idx = res.Move(new VFSManagerEntry());
|
||||
res[idx].path = "$(GameDir)";
|
||||
|
@ -569,7 +569,7 @@ void GLGSRender::DoCmd(const u32 fcmd, const u32 cmd, mem32_ptr_t& args, const u
|
||||
}
|
||||
|
||||
m_frame->Flip();
|
||||
glClear(GL_COLOR_BUFFER_BIT | GL_STENCIL_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
|
||||
//glClear(GL_COLOR_BUFFER_BIT | GL_STENCIL_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
|
||||
}
|
||||
|
||||
m_gcm_current_buffer = args[0];
|
||||
@ -773,69 +773,52 @@ void GLGSRender::DoCmd(const u32 fcmd, const u32 cmd, mem32_ptr_t& args, const u
|
||||
m_surface_offset_b = args[4];
|
||||
m_surface_pitch_b = args[5];
|
||||
|
||||
/*
|
||||
ConLog.Write("surface color format: 0x%x", m_surface_color_format);
|
||||
ConLog.Write("surface depth format: 0x%x", m_surface_depth_format);
|
||||
ConLog.Write("surface type: 0x%x", m_surface_type);
|
||||
ConLog.Write("surface antialias: 0x%x", m_surface_antialias);
|
||||
ConLog.Write("surface width: 0x%x", m_surface_width);
|
||||
ConLog.Write("surface height: 0x%x", m_surface_height);
|
||||
ConLog.Write("surface pitch a: 0x%x", m_surface_pitch_a);
|
||||
ConLog.Write("surface offset a: 0x%x", m_surface_offset_a);
|
||||
ConLog.Write("surface offset z: 0x%x", m_surface_offset_z);
|
||||
ConLog.Write("surface offset b: 0x%x", m_surface_offset_b);
|
||||
ConLog.Write("surface pitch b: 0x%x", m_surface_pitch_b);
|
||||
if(m_surface_offset_a && m_set_context_dma_color_a)
|
||||
{
|
||||
u32 surface_addr = GetAddress(m_surface_offset_a, (m_context_dma_color_a - 0xfeed0000));
|
||||
auto& surface = (const CellGcmSurface&)Memory[surface_addr];
|
||||
ConLog.Write("context_dma_color_a=0x%x", m_context_dma_color_a);
|
||||
ConLog.Write("context a: color format: 0x%x", surface.color_format);
|
||||
ConLog.Write("context a: depth format: 0x%x", surface.depth_format);
|
||||
ConLog.Write("context a: type: 0x%x", surface.type);
|
||||
ConLog.Write("context a: antialias: 0x%x", surface.antialias);
|
||||
ConLog.Write("context a: width: 0x%x", surface.width);
|
||||
ConLog.Write("context a: height: 0x%x", surface.height);
|
||||
}
|
||||
else if(m_surface_offset_z && m_set_context_dma_z)
|
||||
{
|
||||
u32 surface_addr = GetAddress(m_surface_offset_z, m_context_dma_z);
|
||||
auto& surface = (const CellGcmSurface&)Memory[surface_addr];
|
||||
ConLog.Write("m_surface_offset_z=0x%x", m_surface_offset_z);
|
||||
ConLog.Write("context x: color format: 0x%x", surface.color_format);
|
||||
ConLog.Write("context z: depth format: 0x%x", surface.depth_format);
|
||||
ConLog.Write("context z: type: 0x%x", surface.type);
|
||||
ConLog.Write("context z: antialias: 0x%x", surface.antialias);
|
||||
ConLog.Write("context z: width: 0x%x", surface.width);
|
||||
ConLog.Write("context z: height: 0x%x", surface.height);
|
||||
|
||||
m_width = surface.width;
|
||||
m_height = surface.height;
|
||||
}
|
||||
*/
|
||||
m_depth_offset = m_surface_offset_z;
|
||||
|
||||
gcmBuffer* buffers = (gcmBuffer*)Memory.GetMemFromAddr(m_gcm_buffers_addr);
|
||||
m_width = re(buffers[m_gcm_current_buffer].width);
|
||||
m_height = re(buffers[m_gcm_current_buffer].height);
|
||||
|
||||
if(1)
|
||||
break;
|
||||
m_rbo.Create(2);
|
||||
checkForGlError("m_rbo.Create");
|
||||
m_rbo.Bind(0);
|
||||
m_rbo.Storage(GL_RGBA, m_width, m_height);
|
||||
checkForGlError("m_rbo.Storage(GL_RGBA)");
|
||||
m_rbo.Bind(1);
|
||||
|
||||
switch(m_surface_depth_format)
|
||||
{
|
||||
m_rbo.Create(2);
|
||||
checkForGlError("m_rbo.Create");
|
||||
m_rbo.Bind(0);
|
||||
m_rbo.Storage(GL_RGBA, m_width, m_height);
|
||||
checkForGlError("m_rbo.Storage(GL_RGBA)");
|
||||
m_rbo.Bind(1);
|
||||
case 1:
|
||||
m_rbo.Storage(GL_DEPTH_COMPONENT16, m_width, m_height);
|
||||
break;
|
||||
|
||||
case 2:
|
||||
m_rbo.Storage(GL_DEPTH24_STENCIL8, m_width, m_height);
|
||||
checkForGlError("m_rbo.Storage(GL_DEPTH24_STENCIL8)");
|
||||
m_fbo.Create();
|
||||
checkForGlError("m_fbo.Create");
|
||||
m_fbo.Bind();
|
||||
m_fbo.Renderbuffer(GL_COLOR_ATTACHMENT0, m_rbo.GetId(0));
|
||||
checkForGlError("m_fbo.Renderbuffer(GL_COLOR_ATTACHMENT0)");
|
||||
break;
|
||||
|
||||
default:
|
||||
ConLog.Error("Bad depth format! (%d)", m_surface_depth_format);
|
||||
assert(0);
|
||||
break;
|
||||
}
|
||||
checkForGlError("m_rbo.Storage(GL_DEPTH24_STENCIL8)");
|
||||
m_fbo.Create();
|
||||
checkForGlError("m_fbo.Create");
|
||||
m_fbo.Bind();
|
||||
m_fbo.Renderbuffer(GL_COLOR_ATTACHMENT0, m_rbo.GetId(0));
|
||||
checkForGlError("m_fbo.Renderbuffer(GL_COLOR_ATTACHMENT0)");
|
||||
|
||||
if(m_surface_depth_format == 2)
|
||||
{
|
||||
m_fbo.Renderbuffer(GL_DEPTH_STENCIL_ATTACHMENT, m_rbo.GetId(1));
|
||||
checkForGlError("m_fbo.Renderbuffer(GL_DEPTH_STENCIL_ATTACHMENT)");
|
||||
}
|
||||
else
|
||||
{
|
||||
m_fbo.Renderbuffer(GL_DEPTH_ATTACHMENT, m_rbo.GetId(1));
|
||||
checkForGlError("m_fbo.Renderbuffer(GL_DEPTH_STENCIL_ATTACHMENT)");
|
||||
}
|
||||
//CMD_LOG("color_format=%d, depth_format=%d, type=%d, antialias=%d, width=%d, height=%d, pitch_a=%d, offset_a=0x%x, offset_z=0x%x, offset_b=0x%x, pitch_b=%d",
|
||||
// color_format, depth_format, type, antialias, width, height, pitch_a, offset_a, offset_z, offset_b, pitch_b);
|
||||
}
|
||||
@ -941,19 +924,10 @@ void GLGSRender::DoCmd(const u32 fcmd, const u32 cmd, mem32_ptr_t& args, const u
|
||||
case NV4097_SET_FRONT_POLYGON_MODE:
|
||||
m_set_front_polygon_mode = true;
|
||||
m_front_polygon_mode = args[0];
|
||||
//glPolygonMode(GL_FRONT, args[0]);
|
||||
break;
|
||||
|
||||
case NV4097_CLEAR_SURFACE:
|
||||
{
|
||||
u32 a0 = args[0];
|
||||
GLbitfield f = 0;
|
||||
if (a0 & 0x1) f |= GL_DEPTH_BUFFER_BIT;
|
||||
if (a0 & 0x2) f |= GL_STENCIL_BUFFER_BIT;
|
||||
if (a0 & 0xF0) f |= GL_COLOR_BUFFER_BIT;
|
||||
glClear(f);
|
||||
checkForGlError("glClear");
|
||||
/*
|
||||
if(m_set_clear_surface)
|
||||
{
|
||||
m_clear_surface_mask |= args[0];
|
||||
@ -963,7 +937,6 @@ void GLGSRender::DoCmd(const u32 fcmd, const u32 cmd, mem32_ptr_t& args, const u
|
||||
m_clear_surface_mask = args[0];
|
||||
m_set_clear_surface = true;
|
||||
}
|
||||
*/
|
||||
}
|
||||
break;
|
||||
|
||||
@ -1021,8 +994,9 @@ void GLGSRender::DoCmd(const u32 fcmd, const u32 cmd, mem32_ptr_t& args, const u
|
||||
{
|
||||
for(u32 c=0; c<count; ++c)
|
||||
{
|
||||
const u32 first = args[c] & 0xffffff;
|
||||
const u32 _count = (args[c] >> 24) + 1;
|
||||
u32 ac = args[c];
|
||||
const u32 first = ac & 0xffffff;
|
||||
const u32 _count = (ac >> 24) + 1;
|
||||
|
||||
LoadVertexData(first, _count);
|
||||
|
||||
@ -1508,7 +1482,7 @@ void GLGSRender::DoCmd(const u32 fcmd, const u32 cmd, mem32_ptr_t& args, const u
|
||||
|
||||
case NV4097_SET_SURFACE_PITCH_Z:
|
||||
{
|
||||
//TODO
|
||||
m_depth_pitch = args[0];
|
||||
}
|
||||
break;
|
||||
|
||||
@ -1580,10 +1554,9 @@ void GLGSRender::DoCmd(const u32 fcmd, const u32 cmd, mem32_ptr_t& args, const u
|
||||
case NV4097_SET_ZSTENCIL_CLEAR_VALUE:
|
||||
{
|
||||
u32 clear_valuei = args[0];
|
||||
//double clear_valuef = (double)clear_valuei / 0xffffffff;
|
||||
//glClearDepth(clear_valuef);
|
||||
double clear_valuef = (double)clear_valuei / 0xffffffff;
|
||||
glClearDepth(clear_valuef);
|
||||
glClearStencil(clear_valuei);
|
||||
glClear(GL_STENCIL_BUFFER_BIT);
|
||||
}
|
||||
break;
|
||||
|
||||
@ -1897,6 +1870,59 @@ bool GLGSRender::LoadProgram()
|
||||
return true;
|
||||
}
|
||||
|
||||
void GLGSRender::WriteDepthBuffer()
|
||||
{
|
||||
if(!m_set_context_dma_z)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
u32 address = GetAddress(m_depth_offset, m_context_dma_z - 0xfeed0000);
|
||||
if(!Memory.IsGoodAddr(address))
|
||||
{
|
||||
ConLog.Warning("Bad depth address: address=0x%x, offset=0x%x, dma=0x%x", address, m_depth_offset, m_context_dma_z);
|
||||
return;
|
||||
}
|
||||
|
||||
u8* dst = &Memory[address];
|
||||
//m_fbo.Bind(GL_READ_FRAMEBUFFER);
|
||||
//glPixelStorei(GL_PACK_ROW_LENGTH, m_depth_pitch);
|
||||
|
||||
m_fbo.Bind(GL_READ_FRAMEBUFFER);
|
||||
GLuint depth_tex;
|
||||
glGenTextures(1, &depth_tex);
|
||||
glBindTexture(GL_TEXTURE_2D, depth_tex);
|
||||
glCopyTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT24, 0, 0, m_width, m_height, 0);
|
||||
checkForGlError("glCopyTexImage2D");
|
||||
glGetTexImage(GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT, GL_FLOAT, dst);
|
||||
checkForGlError("glGetTexImage");
|
||||
glDeleteTextures(1, &depth_tex);
|
||||
wxFile f("depth.raw", wxFile::write);
|
||||
f.Write(dst, m_width * m_height * 4);
|
||||
m_fbo.Bind();
|
||||
/*
|
||||
GLBufferObject pbo;
|
||||
pbo.Create(GL_PIXEL_PACK_BUFFER);
|
||||
pbo.Bind();
|
||||
glReadPixels(0, 0, m_width, m_height, GL_DEPTH_COMPONENT, GL_FLOAT, 0);
|
||||
GLuint *src = (GLuint*)glMapBuffer(GL_PIXEL_PACK_BUFFER, GL_READ_ONLY);
|
||||
if(src)
|
||||
{
|
||||
wxFile f("depth.raw", wxFile::write);
|
||||
f.Write(src, m_width * m_height * 4);
|
||||
memcpy(dst, src, m_width * m_height * 4);
|
||||
glUnmapBuffer(GL_PIXEL_PACK_BUFFER);
|
||||
}
|
||||
else
|
||||
{
|
||||
ConLog.Error("glMapBuffer failed.");
|
||||
}
|
||||
pbo.UnBind();
|
||||
pbo.Delete();
|
||||
*/
|
||||
Emu.Pause();
|
||||
}
|
||||
|
||||
void GLGSRender::ExecCMD()
|
||||
{
|
||||
if(LoadProgram())
|
||||
@ -1938,7 +1964,7 @@ void GLGSRender::ExecCMD()
|
||||
GLbitfield f = 0;
|
||||
if (m_clear_surface_mask & 0x1) f |= GL_DEPTH_BUFFER_BIT;
|
||||
if (m_clear_surface_mask & 0x2) f |= GL_STENCIL_BUFFER_BIT;
|
||||
if (m_clear_surface_mask & 0xF0) f |= GL_COLOR_BUFFER_BIT;
|
||||
if ((m_clear_surface_mask & 0xF0) == 0xF0) f |= GL_COLOR_BUFFER_BIT;
|
||||
glClear(f);
|
||||
}
|
||||
|
||||
@ -1972,6 +1998,24 @@ void GLGSRender::ExecCMD()
|
||||
checkForGlError("m_set_clip_plane");
|
||||
}
|
||||
|
||||
if(m_set_stencil_fail && m_set_stencil_zfail && m_set_stencil_zpass)
|
||||
{
|
||||
glStencilOp(m_stencil_fail, m_stencil_zfail, m_stencil_zpass);
|
||||
checkForGlError("glStencilOp");
|
||||
}
|
||||
|
||||
if(m_set_stencil_mask)
|
||||
{
|
||||
glStencilMask(m_stencil_mask);
|
||||
checkForGlError("glStencilMask");
|
||||
}
|
||||
|
||||
if(m_set_stencil_func && m_set_stencil_func_ref && m_set_stencil_func_mask)
|
||||
{
|
||||
glStencilFunc(m_stencil_func, m_stencil_func_ref, m_stencil_func_mask);
|
||||
checkForGlError("glStencilFunc");
|
||||
}
|
||||
|
||||
if(m_set_two_sided_stencil_test_enable)
|
||||
{
|
||||
if(m_set_back_stencil_fail && m_set_back_stencil_zfail && m_set_back_stencil_zpass)
|
||||
@ -1993,24 +2037,6 @@ void GLGSRender::ExecCMD()
|
||||
}
|
||||
}
|
||||
|
||||
if(m_set_stencil_fail && m_set_stencil_zfail && m_set_stencil_zpass)
|
||||
{
|
||||
glStencilOpSeparate(GL_FRONT, m_stencil_fail, m_stencil_zfail, m_stencil_zpass);
|
||||
checkForGlError("glStencilOpSeparate(GL_FRONT)");
|
||||
}
|
||||
|
||||
if(m_set_stencil_mask)
|
||||
{
|
||||
glStencilMaskSeparate(GL_FRONT, m_stencil_mask);
|
||||
checkForGlError("glStencilMaskSeparate(GL_FRONT)");
|
||||
}
|
||||
|
||||
if(m_set_stencil_func && m_set_stencil_func_ref && m_set_stencil_func_mask)
|
||||
{
|
||||
glStencilFuncSeparate(GL_FRONT, m_stencil_func, m_stencil_func_ref, m_stencil_func_mask);
|
||||
checkForGlError("glStencilFuncSeparate(GL_FRONT)");
|
||||
}
|
||||
|
||||
if(m_set_shade_mode)
|
||||
{
|
||||
glShadeModel(m_shade_mode);
|
||||
@ -2149,6 +2175,8 @@ void GLGSRender::ExecCMD()
|
||||
}
|
||||
|
||||
m_fragment_constants.Clear();
|
||||
|
||||
//WriteDepthBuffer();
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -556,6 +556,7 @@ private:
|
||||
virtual void Draw();
|
||||
virtual void Close();
|
||||
bool LoadProgram();
|
||||
void WriteDepthBuffer();
|
||||
|
||||
public:
|
||||
void DoCmd(const u32 fcmd, const u32 cmd, mem32_ptr_t& args, const u32 count);
|
||||
|
@ -295,10 +295,10 @@ void VertexDecompilerThread::Task()
|
||||
case 0x02: AddVecCode("(" + GetSRC(0) + " * " + GetSRC(1) + ")"); break; //MUL
|
||||
case 0x03: AddVecCode("(" + GetSRC(0) + " + " + GetSRC(2) + ")"); break; //ADD
|
||||
case 0x04: AddVecCode("(" + GetSRC(0) + " * " + GetSRC(1) + " + " + GetSRC(2) + ")"); break; //MAD
|
||||
case 0x05: AddVecCode("vec4(dot(" + GetSRC(0) + ".xyz, " + GetSRC(1) + ".xyz)).xxxx"); break; //DP3
|
||||
case 0x06: AddVecCode("vec4(dot(vec4(" + GetSRC(0) + ".xyz, 1), " + GetSRC(1) + ")).xxxx"); break; //DPH
|
||||
case 0x07: AddVecCode("vec4(dot(" + GetSRC(0) + ", " + GetSRC(1) + ")).xxxx"); break; //DP4
|
||||
case 0x08: AddVecCode("vec4(distance(" + GetSRC(0) + ", " + GetSRC(1) + ")).xxxx"); break; //DST
|
||||
case 0x05: AddVecCode("vec4(dot(" + GetSRC(0) + ".xyz, " + GetSRC(1) + ".xyz), 0, 0, 0).xxxx"); break; //DP3
|
||||
case 0x06: AddVecCode("vec4(dot(vec4(" + GetSRC(0) + ".xyz, 1), " + GetSRC(1) + "), 0, 0, 0).xxxx"); break; //DPH
|
||||
case 0x07: AddVecCode("vec4(dot(" + GetSRC(0) + ", " + GetSRC(1) + "), 0, 0, 0).xxxx"); break; //DP4
|
||||
case 0x08: AddVecCode("vec4(distance(" + GetSRC(0) + ", " + GetSRC(1) + "), 0, 0, 0).xxxx"); break; //DST
|
||||
case 0x09: AddVecCode("min(" + GetSRC(0) + ", " + GetSRC(1) + ")"); break; //MIN
|
||||
case 0x0a: AddVecCode("max(" + GetSRC(0) + ", " + GetSRC(1) + ")"); break; //MAX
|
||||
case 0x0b: AddVecCode("vec4(lessThan(" + GetSRC(0) + ", " + GetSRC(1) + "))"); break; //SLT
|
||||
|
@ -47,6 +47,10 @@ public:
|
||||
|
||||
bool m_set_clear_surface;
|
||||
u32 m_clear_surface_mask;
|
||||
u8 m_clear_surface_color_r;
|
||||
u8 m_clear_surface_color_g;
|
||||
u8 m_clear_surface_color_b;
|
||||
u8 m_clear_surface_color_a;
|
||||
|
||||
bool m_set_blend_sfactor;
|
||||
u16 m_blend_sfactor_rgb;
|
||||
@ -205,23 +209,33 @@ public:
|
||||
bool m_set_alpha_ref;
|
||||
u32 m_alpha_ref;
|
||||
|
||||
u32 m_depth_offset;
|
||||
u32 m_depth_pitch;
|
||||
|
||||
u8 m_begin_end;
|
||||
|
||||
public:
|
||||
ExecRSXCMDdata()
|
||||
{
|
||||
m_set_alpha_test = false;
|
||||
m_set_blend = false;
|
||||
m_set_depth_bounds_test = false;
|
||||
m_depth_test_enable = false;
|
||||
m_set_logic_op = false;
|
||||
m_set_cull_face_enable = false;
|
||||
m_set_dither = false;
|
||||
m_set_stencil_test = false;
|
||||
m_set_line_smooth = false;
|
||||
m_set_poly_smooth = false;
|
||||
|
||||
Reset();
|
||||
}
|
||||
|
||||
virtual void Reset()
|
||||
{
|
||||
m_set_color_mask = false;
|
||||
m_set_alpha_test = false;
|
||||
m_set_blend = false;
|
||||
m_set_depth_bounds_test = false;
|
||||
m_set_clip = false;
|
||||
m_set_depth_func = false;
|
||||
m_depth_test_enable = false;
|
||||
m_set_viewport_horizontal = false;
|
||||
m_set_viewport_vertical = false;
|
||||
m_set_scissor_horizontal = false;
|
||||
@ -230,10 +244,6 @@ public:
|
||||
m_set_clear_surface = false;
|
||||
m_set_blend_sfactor = false;
|
||||
m_set_blend_dfactor = false;
|
||||
m_set_logic_op = false;
|
||||
m_set_cull_face_enable = false;
|
||||
m_set_dither = false;
|
||||
m_set_stencil_test = false;
|
||||
m_set_stencil_mask = false;
|
||||
m_set_stencil_func = false;
|
||||
m_set_stencil_func_ref = false;
|
||||
@ -251,8 +261,6 @@ public:
|
||||
m_set_back_stencil_zpass = false;
|
||||
m_set_blend_equation = false;
|
||||
m_set_depth_mask = false;
|
||||
m_set_line_smooth = false;
|
||||
m_set_poly_smooth = false;
|
||||
m_set_line_width = false;
|
||||
m_set_shade_mode = false;
|
||||
m_set_blend_color = false;
|
||||
|
@ -107,6 +107,12 @@ int cellFsRead(u32 fd, u32 buf_addr, u64 nbytes, mem64_t nread)
|
||||
if(!sys_fs.CheckId(fd, id)) return CELL_ESRCH;
|
||||
vfsStream& file = *(vfsStream*)id.m_data;
|
||||
|
||||
if(Memory.IsGoodAddr(buf_addr) && !Memory.IsGoodAddr(buf_addr, nbytes))
|
||||
{
|
||||
MemoryBlock& block = Memory.GetMemByAddr(buf_addr);
|
||||
nbytes = block.GetSize() - (buf_addr - block.GetStartAddr());
|
||||
}
|
||||
|
||||
const u64 res = nbytes ? file.Read(Memory.GetMemFromAddr(buf_addr), nbytes) : 0;
|
||||
|
||||
if(nread.IsGood())
|
||||
@ -173,38 +179,40 @@ int cellFsStat(const u32 path_addr, mem_struct_ptr_t<CellFsStat> sb)
|
||||
const wxString& path = Memory.ReadString(path_addr);
|
||||
sys_fs.Log("cellFsFstat(path: %s, sb_addr: 0x%x)", path, sb.GetAddr());
|
||||
|
||||
// Check if path is a mount point. (TODO: Add information in sb_addr)
|
||||
for(u32 i=0; i<Emu.GetVFS().m_devices.GetCount(); ++i)
|
||||
{
|
||||
if (path == Emu.GetVFS().m_devices[i].GetPs3Path().RemoveLast(1))
|
||||
{
|
||||
sys_fs.Log("cellFsFstat: '%s' is a mount point.", path);
|
||||
return CELL_OK;
|
||||
}
|
||||
}
|
||||
|
||||
auto f = Emu.OpenFile(path);
|
||||
|
||||
if(!f->IsOpened())
|
||||
{
|
||||
sys_fs.Warning("cellFsFstat: '%s' not found.", path);
|
||||
return CELL_ENOENT;
|
||||
}
|
||||
|
||||
sb->st_mode =
|
||||
CELL_FS_S_IRUSR | CELL_FS_S_IWUSR | CELL_FS_S_IXUSR |
|
||||
CELL_FS_S_IRGRP | CELL_FS_S_IWGRP | CELL_FS_S_IXGRP |
|
||||
CELL_FS_S_IROTH | CELL_FS_S_IWOTH | CELL_FS_S_IXOTH;
|
||||
|
||||
sb->st_mode |= CELL_FS_S_IFREG; //TODO: dir CELL_FS_S_IFDIR
|
||||
sb->st_uid = 0;
|
||||
sb->st_gid = 0;
|
||||
sb->st_atime = 0; //TODO
|
||||
sb->st_mtime = 0; //TODO
|
||||
sb->st_ctime = 0; //TODO
|
||||
sb->st_size = f->GetSize();
|
||||
sb->st_blksize = 4096;
|
||||
|
||||
// Check if path is a mount point. (TODO: Add information in sb_addr)
|
||||
for(u32 i=0; i<Emu.GetVFS().m_devices.GetCount(); ++i)
|
||||
{
|
||||
if(path.CmpNoCase(Emu.GetVFS().m_devices[i].GetPs3Path().RemoveLast(1)) == 0)
|
||||
{
|
||||
sys_fs.Log("cellFsFstat: '%s' is a mount point.", path);
|
||||
sb->st_mode |= CELL_FS_S_IFDIR;
|
||||
return CELL_OK;
|
||||
}
|
||||
}
|
||||
|
||||
vfsFile f(path);
|
||||
|
||||
if(!f.IsOpened())
|
||||
{
|
||||
sys_fs.Warning("cellFsFstat: '%s' not found.", path);
|
||||
return CELL_ENOENT;
|
||||
}
|
||||
|
||||
sb->st_mode |= CELL_FS_S_IFREG; //TODO: dir CELL_FS_S_IFDIR
|
||||
sb->st_size = f.GetSize();
|
||||
|
||||
return CELL_OK;
|
||||
}
|
||||
|
||||
@ -307,19 +315,13 @@ int cellFsFtruncate(u32 fd, u64 size)
|
||||
vfsStream& file = *(vfsStream*)id.m_data;
|
||||
u64 initialSize = file.GetSize();
|
||||
|
||||
if (initialSize < size) // Is there any better way to fill the remaining bytes with 0, without allocating huge buffers in memory, or writing such a spaghetti code?
|
||||
if (initialSize < size)
|
||||
{
|
||||
u64 last_pos = file.Tell();
|
||||
file.Seek(0, vfsSeekEnd);
|
||||
char* nullblock = (char*)calloc(4096, sizeof(char));
|
||||
for(u64 i = (size-initialSize)/4096; i > 0; i--){
|
||||
file.Write(nullblock, 4096);
|
||||
}
|
||||
free(nullblock);
|
||||
char nullbyte = 0;
|
||||
for(u64 i = (size-initialSize)%4096; i > 0; i--){
|
||||
file.Write(&nullbyte, 1);
|
||||
}
|
||||
static const char nullbyte = 0;
|
||||
file.Seek(size-initialSize-1, vfsSeekCur);
|
||||
file.Write(&nullbyte, sizeof(char));
|
||||
file.Seek(last_pos, vfsSeekSet);
|
||||
}
|
||||
|
||||
@ -336,29 +338,22 @@ int cellFsTruncate(u32 path_addr, u64 size)
|
||||
const wxString& path = Memory.ReadString(path_addr);
|
||||
sys_fs.Log("cellFsTruncate(path: %s, size: %lld)", path, size);
|
||||
|
||||
vfsStream* f = Emu.GetVFS().Open(path, vfsRead);
|
||||
if(!f || !f->IsOpened())
|
||||
vfsFile f(path, vfsReadWrite);
|
||||
if(!f.IsOpened())
|
||||
{
|
||||
sys_fs.Warning("cellFsTruncate: '%s' not found.", path);
|
||||
Emu.GetVFS().Close(f);
|
||||
return CELL_ENOENT;
|
||||
}
|
||||
u64 initialSize = f->GetSize();
|
||||
u64 initialSize = f.GetSize();
|
||||
|
||||
if (initialSize < size) // Is there any better way to fill the remaining bytes with 0, without allocating huge buffers in memory, or writing such a spaghetti code?
|
||||
if (initialSize < size)
|
||||
{
|
||||
u64 last_pos = f->Tell();
|
||||
f->Seek(0, vfsSeekEnd);
|
||||
char* nullblock = (char*)calloc(4096, sizeof(char));
|
||||
for(u64 i = (size-initialSize)/4096; i > 0; i--){
|
||||
f->Write(nullblock, 4096);
|
||||
}
|
||||
free(nullblock);
|
||||
char nullbyte = 0;
|
||||
for(u64 i = (size-initialSize)%4096; i > 0; i--){
|
||||
f->Write(&nullbyte, 1);
|
||||
}
|
||||
f->Seek(last_pos, vfsSeekSet);
|
||||
u64 last_pos = f.Tell();
|
||||
f.Seek(0, vfsSeekEnd);
|
||||
static const char nullbyte = 0;
|
||||
f.Seek(size-initialSize-1, vfsSeekCur);
|
||||
f.Write(&nullbyte, sizeof(char));
|
||||
f.Seek(last_pos, vfsSeekSet);
|
||||
}
|
||||
|
||||
if (initialSize > size)
|
||||
@ -366,7 +361,6 @@ int cellFsTruncate(u32 path_addr, u64 size)
|
||||
// (TODO)
|
||||
}
|
||||
|
||||
Emu.GetVFS().Close(f);
|
||||
return CELL_OK;
|
||||
}
|
||||
|
||||
|
@ -56,6 +56,8 @@ enum FsDirentType
|
||||
CELL_FS_TYPE_SYMLINK = 3,
|
||||
};
|
||||
|
||||
#pragma pack(4)
|
||||
|
||||
struct CellFsStat
|
||||
{
|
||||
be_t<u32> st_mode;
|
||||
@ -79,4 +81,6 @@ struct CellFsDirent
|
||||
u8 d_type;
|
||||
u8 d_namlen;
|
||||
char d_name[CELL_MAX_FS_FILE_NAME_LENGTH + 1];
|
||||
};
|
||||
};
|
||||
|
||||
#pragma pack()
|
@ -449,7 +449,7 @@ void InterpreterDisAsmFrame::DoStep(wxCommandEvent& WXUNUSED(event))
|
||||
void InterpreterDisAsmFrame::InstrKey(wxListEvent& event)
|
||||
{
|
||||
long i = m_list->GetFirstSelected();
|
||||
if(i < 0) return;
|
||||
if(i < 0 || !CPU) return;
|
||||
|
||||
const u64 start_pc = PC - m_item_count*4;
|
||||
const u64 pc = start_pc + i*4;
|
||||
|
@ -133,7 +133,7 @@
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||
<ClCompile>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<WarningLevel>TurnOffAllWarnings</WarningLevel>
|
||||
<Optimization>Full</Optimization>
|
||||
<FunctionLevelLinking>true</FunctionLevelLinking>
|
||||
<IntrinsicFunctions>true</IntrinsicFunctions>
|
||||
|
Loading…
Reference in New Issue
Block a user