mirror of
https://github.com/RPCS3/rpcs3.git
synced 2025-07-12 17:58:37 +12:00
Merge branch 'master' of https://github.com/DHrpcs3/rpcs3
This commit is contained in:
commit
f8d9242743
16 changed files with 1015 additions and 865 deletions
|
@ -1,6 +1,6 @@
|
||||||
cmake_minimum_required(VERSION 2.8)
|
cmake_minimum_required(VERSION 2.8)
|
||||||
|
|
||||||
set (CMAKE_MODULE_PATH "${CMAKE_SOURCE_DIR}/rpcs3/cmake_modules")
|
set (CMAKE_MODULE_PATH "${CMAKE_CURRENT_LIST_DIR}/cmake_modules")
|
||||||
include(cotire)
|
include(cotire)
|
||||||
|
|
||||||
project(rpcs3)
|
project(rpcs3)
|
||||||
|
|
|
@ -156,9 +156,9 @@ int decrypt_data(rFile *in, rFile *out, EDAT_SDAT_HEADER *edat, NPD_HEADER *npd,
|
||||||
int length = 0;
|
int length = 0;
|
||||||
int compression_end = 0;
|
int compression_end = 0;
|
||||||
|
|
||||||
if ((edat->flags & EDAT_FLAG_0x3C) != 0 || (edat->flags & EDAT_FLAG_0x3D) != 0)
|
if ((edat->flags & EDAT_FLAG_0x04) != 0)
|
||||||
{
|
{
|
||||||
LOG_ERROR(LOADER, "EDAT: Flag 0x3C/0x3D EDAT files are unsupported yet");
|
LOG_ERROR(LOADER, "EDAT: Flag 0x04 is not yet supported");
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -5,12 +5,11 @@
|
||||||
#define SDAT_FLAG 0x01000000
|
#define SDAT_FLAG 0x01000000
|
||||||
#define EDAT_COMPRESSED_FLAG 0x00000001
|
#define EDAT_COMPRESSED_FLAG 0x00000001
|
||||||
#define EDAT_FLAG_0x02 0x00000002
|
#define EDAT_FLAG_0x02 0x00000002
|
||||||
|
#define EDAT_FLAG_0x04 0x00000004
|
||||||
#define EDAT_ENCRYPTED_KEY_FLAG 0x00000008
|
#define EDAT_ENCRYPTED_KEY_FLAG 0x00000008
|
||||||
#define EDAT_FLAG_0x10 0x00000010
|
#define EDAT_FLAG_0x10 0x00000010
|
||||||
#define EDAT_FLAG_0x20 0x00000020
|
#define EDAT_FLAG_0x20 0x00000020
|
||||||
#define EDAT_DEBUG_DATA_FLAG 0x80000000
|
#define EDAT_DEBUG_DATA_FLAG 0x80000000
|
||||||
#define EDAT_FLAG_0x3C 0x0000003C
|
|
||||||
#define EDAT_FLAG_0x3D 0x0000003D
|
|
||||||
|
|
||||||
typedef struct
|
typedef struct
|
||||||
{
|
{
|
||||||
|
|
1380
rpcs3/Emu/GS/GCM.h
1380
rpcs3/Emu/GS/GCM.h
File diff suppressed because it is too large
Load diff
|
@ -248,7 +248,7 @@ template<typename T> std::string GLFragmentDecompilerThread::GetSRC(T src)
|
||||||
std::string GLFragmentDecompilerThread::BuildCode()
|
std::string GLFragmentDecompilerThread::BuildCode()
|
||||||
{
|
{
|
||||||
//main += fmt::Format("\tgl_FragColor = %c0;\n", m_ctrl & 0x40 ? 'r' : 'h');
|
//main += fmt::Format("\tgl_FragColor = %c0;\n", m_ctrl & 0x40 ? 'r' : 'h');
|
||||||
static const std::pair<std::string, std::string> table[] =
|
const std::pair<std::string, std::string> table[] =
|
||||||
{
|
{
|
||||||
{ "ocol0", m_ctrl & 0x40 ? "r0" : "h0" },
|
{ "ocol0", m_ctrl & 0x40 ? "r0" : "h0" },
|
||||||
{ "ocol1", m_ctrl & 0x40 ? "r2" : "h2" },
|
{ "ocol1", m_ctrl & 0x40 ? "r2" : "h2" },
|
||||||
|
|
|
@ -353,7 +353,7 @@ std::string GLVertexDecompilerThread::BuildCode()
|
||||||
{ "tc6", true, "dst_reg13", "", false },
|
{ "tc6", true, "dst_reg13", "", false },
|
||||||
{ "tc7", true, "dst_reg14", "", false },
|
{ "tc7", true, "dst_reg14", "", false },
|
||||||
{ "tc8", true, "dst_reg15", "", false },
|
{ "tc8", true, "dst_reg15", "", false },
|
||||||
{ "tc9", true, "dst_reg6", "", false }
|
{ "tc9", true, "dst_reg6", "", false } // In this line, dst_reg6 is correct since dst_reg goes from 0 to 15.
|
||||||
};
|
};
|
||||||
|
|
||||||
std::string f;
|
std::string f;
|
||||||
|
|
|
@ -1524,7 +1524,7 @@ void RSXThread::DoCmd(const u32 fcmd, const u32 cmd, mem32_ptr_t args, const u32
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
// Anti aliasing
|
// Anti-aliasing
|
||||||
case NV4097_SET_ANTI_ALIASING_CONTROL:
|
case NV4097_SET_ANTI_ALIASING_CONTROL:
|
||||||
{
|
{
|
||||||
// TODO:
|
// TODO:
|
||||||
|
@ -1969,8 +1969,11 @@ void RSXThread::DoCmd(const u32 fcmd, const u32 cmd, mem32_ptr_t args, const u32
|
||||||
|
|
||||||
case NV309E_SET_FORMAT:
|
case NV309E_SET_FORMAT:
|
||||||
{
|
{
|
||||||
if (ARGS(0))
|
const u8 height = ARGS(0) >> 24;
|
||||||
LOG_WARNING(RSX, "NV309E_SET_FORMAT: %x", ARGS(0));
|
const u8 width = ARGS(0) >> 16;
|
||||||
|
const u8 format = ARGS(0);
|
||||||
|
const u32 offset = ARGS(1);
|
||||||
|
LOG_WARNING(RSX, "NV309E_SET_FORMAT: Format:0x%x, Width:%d, Height:%d, Offset:0x%x", format, width, height, offset);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
@ -2041,7 +2044,7 @@ void RSXThread::DoCmd(const u32 fcmd, const u32 cmd, mem32_ptr_t args, const u32
|
||||||
case NV308A_SET_CONTEXT_SURFACE:
|
case NV308A_SET_CONTEXT_SURFACE:
|
||||||
{
|
{
|
||||||
if (ARGS(0))
|
if (ARGS(0))
|
||||||
LOG_WARNING(RSX, "NV3089_SET_CONTEXT_SURFACE: %x", ARGS(0));
|
LOG_WARNING(RSX, "NV308A_SET_CONTEXT_SURFACE: %x", ARGS(0));
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
|
|
@ -29,49 +29,33 @@ int cellGifDecOpen(u32 mainHandle, mem32_t subHandle, const mem_ptr_t<CellGifDec
|
||||||
{
|
{
|
||||||
if (!subHandle.IsGood() || !src.IsGood())
|
if (!subHandle.IsGood() || !src.IsGood())
|
||||||
return CELL_GIFDEC_ERROR_ARG;
|
return CELL_GIFDEC_ERROR_ARG;
|
||||||
/*
|
|
||||||
vfsStream* stream;
|
|
||||||
|
|
||||||
switch(src->srcSelect)
|
|
||||||
{
|
|
||||||
case CELL_GIFDEC_FILE:
|
|
||||||
stream = Emu.GetVFS().Open(src->fileName.GetString(), vfsRead);
|
|
||||||
stream->Seek(src->fileOffset);
|
|
||||||
src->fileSize;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case CELL_GIFDEC_BUFFER:
|
|
||||||
if(src->streamSize < 5)
|
|
||||||
return CELL_GIFDEC_ERROR_ARG;
|
|
||||||
|
|
||||||
stream = new vfsStreamMemory(src->streamPtr.GetAddr(), src->streamSize);
|
|
||||||
break;
|
|
||||||
|
|
||||||
default:
|
|
||||||
return CELL_GIFDEC_ERROR_ARG;
|
|
||||||
}
|
|
||||||
|
|
||||||
if(!stream->IsOpened())
|
|
||||||
{
|
|
||||||
return CELL_GIFDEC_ERROR_OPEN_FILE;
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
|
|
||||||
CellGifDecSubHandle *current_subHandle = new CellGifDecSubHandle;
|
CellGifDecSubHandle *current_subHandle = new CellGifDecSubHandle;
|
||||||
|
current_subHandle->fd = 0;
|
||||||
|
current_subHandle->src = *src;
|
||||||
|
|
||||||
|
switch(src->srcSelect.ToBE())
|
||||||
|
{
|
||||||
|
case se32(CELL_GIFDEC_BUFFER):
|
||||||
|
current_subHandle->fileSize = src->streamSize.ToLE();
|
||||||
|
break;
|
||||||
|
|
||||||
|
case se32(CELL_GIFDEC_FILE):
|
||||||
// Get file descriptor
|
// Get file descriptor
|
||||||
MemoryAllocator<be_t<u32>> fd;
|
MemoryAllocator<be_t<u32>> fd;
|
||||||
int ret = cellFsOpen(src->fileName, 0, fd, 0, 0);
|
int ret = cellFsOpen(src->fileName, 0, fd.GetAddr(), 0, 0);
|
||||||
current_subHandle->fd = fd->ToLE();
|
current_subHandle->fd = fd->ToLE();
|
||||||
if(ret != CELL_OK) return CELL_GIFDEC_ERROR_OPEN_FILE;
|
if (ret != CELL_OK) return CELL_GIFDEC_ERROR_OPEN_FILE;
|
||||||
|
|
||||||
// Get size of file
|
// Get size of file
|
||||||
MemoryAllocator<CellFsStat> sb; // Alloc a CellFsStat struct
|
MemoryAllocator<CellFsStat> sb; // Alloc a CellFsStat struct
|
||||||
ret = cellFsFstat(current_subHandle->fd, sb.GetAddr());
|
ret = cellFsFstat(current_subHandle->fd, sb.GetAddr());
|
||||||
if(ret != CELL_OK) return ret;
|
if (ret != CELL_OK) return ret;
|
||||||
current_subHandle->fileSize = sb->st_size; // Get CellFsStat.st_size
|
current_subHandle->fileSize = sb->st_size; // Get CellFsStat.st_size
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
// From now, every u32 subHandle argument is a pointer to a CellPngDecSubHandle struct.
|
// From now, every u32 subHandle argument is a pointer to a CellGifDecSubHandle struct.
|
||||||
subHandle = cellGifDec->GetNewId(current_subHandle);
|
subHandle = cellGifDec->GetNewId(current_subHandle);
|
||||||
|
|
||||||
return CELL_OK;
|
return CELL_OK;
|
||||||
|
@ -94,8 +78,20 @@ int cellGifDecReadHeader(u32 mainHandle, u32 subHandle, mem_ptr_t<CellGifDecInfo
|
||||||
MemoryAllocator<u8> buffer(13); // Alloc buffer for GIF header
|
MemoryAllocator<u8> buffer(13); // Alloc buffer for GIF header
|
||||||
MemoryAllocator<be_t<u64>> pos, nread;
|
MemoryAllocator<be_t<u64>> pos, nread;
|
||||||
|
|
||||||
cellFsLseek(fd, 0, CELL_SEEK_SET, pos);
|
switch(subHandle_data->src.srcSelect.ToBE())
|
||||||
|
{
|
||||||
|
case se32(CELL_GIFDEC_BUFFER):
|
||||||
|
if (!Memory.Copy(buffer.GetAddr(), subHandle_data->src.streamPtr.ToLE(), buffer.GetSize())) {
|
||||||
|
cellGifDec->Error("cellGifDecReadHeader() failed ()");
|
||||||
|
return CELL_EFAULT;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case se32(CELL_GIFDEC_FILE):
|
||||||
|
cellFsLseek(fd, 0, CELL_SEEK_SET, pos.GetAddr());
|
||||||
cellFsRead(fd, buffer.GetAddr(), buffer.GetSize(), nread);
|
cellFsRead(fd, buffer.GetAddr(), buffer.GetSize(), nread);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
if (*buffer.To<be_t<u32>>(0) != 0x47494638 ||
|
if (*buffer.To<be_t<u32>>(0) != 0x47494638 ||
|
||||||
(*buffer.To<u16>(4) != 0x6139 && *buffer.To<u16>(4) != 0x6137)) // Error: The first 6 bytes are not a valid GIF signature
|
(*buffer.To<u16>(4) != 0x6139 && *buffer.To<u16>(4) != 0x6137)) // Error: The first 6 bytes are not a valid GIF signature
|
||||||
|
@ -166,34 +162,108 @@ int cellGifDecDecodeData(u32 mainHandle, u32 subHandle, mem8_ptr_t data, const m
|
||||||
//Copy the GIF file to a buffer
|
//Copy the GIF file to a buffer
|
||||||
MemoryAllocator<unsigned char> gif(fileSize);
|
MemoryAllocator<unsigned char> gif(fileSize);
|
||||||
MemoryAllocator<u64> pos, nread;
|
MemoryAllocator<u64> pos, nread;
|
||||||
cellFsLseek(fd, 0, CELL_SEEK_SET, pos);
|
|
||||||
cellFsRead(fd, gif.GetAddr(), gif.GetSize(), nread);
|
|
||||||
|
|
||||||
//Decode GIF file. (TODO: Is there any faster alternative? Can we do it without external libraries?)
|
switch(subHandle_data->src.srcSelect.ToBE())
|
||||||
int width, height, actual_components;
|
|
||||||
std::shared_ptr<unsigned char> image(stbi_load_from_memory(gif, fileSize, &width, &height, &actual_components, 4));
|
|
||||||
if (!image)
|
|
||||||
return CELL_GIFDEC_ERROR_STREAM_FORMAT;
|
|
||||||
|
|
||||||
uint image_size = width * height * 4;
|
|
||||||
|
|
||||||
switch((u32)current_outParam.outputColorSpace)
|
|
||||||
{
|
{
|
||||||
case CELL_GIFDEC_RGBA:
|
case se32(CELL_GIFDEC_BUFFER):
|
||||||
if (!Memory.CopyFromReal(data.GetAddr(), image.get(), image_size))
|
if (!Memory.Copy(gif.GetAddr(), subHandle_data->src.streamPtr.ToLE(), gif.GetSize())) {
|
||||||
{
|
cellGifDec->Error("cellGifDecDecodeData() failed (I)");
|
||||||
cellGifDec->Error("cellGifDecDecodeData() failed (dataa_addr=0x%x)", data.GetAddr());
|
|
||||||
return CELL_EFAULT;
|
return CELL_EFAULT;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case CELL_GIFDEC_ARGB:
|
case se32(CELL_GIFDEC_FILE):
|
||||||
for(uint i = 0; i < image_size; i+=4)
|
cellFsLseek(fd, 0, CELL_SEEK_SET, pos.GetAddr());
|
||||||
|
cellFsRead(fd, gif.GetAddr(), gif.GetSize(), nread);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
//Decode GIF file. (TODO: Is there any faster alternative? Can we do it without external libraries?)
|
||||||
|
int width, height, actual_components;
|
||||||
|
auto image = std::unique_ptr<unsigned char,decltype(&::free)>
|
||||||
|
(
|
||||||
|
stbi_load_from_memory(gif.GetPtr(), fileSize, &width, &height, &actual_components, 4),
|
||||||
|
&::free
|
||||||
|
);
|
||||||
|
|
||||||
|
if (!image)
|
||||||
|
return CELL_GIFDEC_ERROR_STREAM_FORMAT;
|
||||||
|
|
||||||
|
const int bytesPerLine = dataCtrlParam->outputBytesPerLine;
|
||||||
|
const char nComponents = 4;
|
||||||
|
uint image_size = width * height * nComponents;
|
||||||
|
|
||||||
|
switch((u32)current_outParam.outputColorSpace)
|
||||||
{
|
{
|
||||||
data += image.get()[i+3];
|
case CELL_GIFDEC_RGBA:
|
||||||
data += image.get()[i+0];
|
{
|
||||||
data += image.get()[i+1];
|
if (bytesPerLine > width * nComponents) // Check if we need padding
|
||||||
data += image.get()[i+2];
|
{
|
||||||
|
const int linesize = std::min(bytesPerLine, width * nComponents);
|
||||||
|
for (int i = 0; i < height; i++)
|
||||||
|
{
|
||||||
|
const int dstOffset = i * bytesPerLine;
|
||||||
|
const int srcOffset = width * nComponents * i;
|
||||||
|
if (!Memory.CopyFromReal(data.GetAddr() + dstOffset, &image.get()[srcOffset], linesize))
|
||||||
|
{
|
||||||
|
cellGifDec->Error("cellGifDecDecodeData() failed (II)");
|
||||||
|
return CELL_EFAULT;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (!Memory.CopyFromReal(data.GetAddr(), image.get(), image_size))
|
||||||
|
{
|
||||||
|
cellGifDec->Error("cellGifDecDecodeData() failed (III)");
|
||||||
|
return CELL_EFAULT;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case CELL_GIFDEC_ARGB:
|
||||||
|
{
|
||||||
|
if (bytesPerLine > width * nComponents) // Check if we need padding
|
||||||
|
{
|
||||||
|
//TODO: find out if we can't do padding without an extra copy
|
||||||
|
const int linesize = std::min(bytesPerLine, width * nComponents);
|
||||||
|
char *output = (char *) malloc(linesize);
|
||||||
|
for (int i = 0; i < height; i++)
|
||||||
|
{
|
||||||
|
const int dstOffset = i * bytesPerLine;
|
||||||
|
const int srcOffset = width * nComponents * i;
|
||||||
|
for (int j = 0; j < linesize; j += nComponents)
|
||||||
|
{
|
||||||
|
output[j + 0] = image.get()[srcOffset + j + 3];
|
||||||
|
output[j + 1] = image.get()[srcOffset + j + 0];
|
||||||
|
output[j + 2] = image.get()[srcOffset + j + 1];
|
||||||
|
output[j + 3] = image.get()[srcOffset + j + 2];
|
||||||
|
}
|
||||||
|
if (!Memory.CopyFromReal(data.GetAddr() + dstOffset, output, linesize))
|
||||||
|
{
|
||||||
|
cellGifDec->Error("cellGifDecDecodeData() failed (IV)");
|
||||||
|
return CELL_EFAULT;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
free(output);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
uint* dest = (uint*)new char[image_size];
|
||||||
|
uint* source_current = (uint*)&(image.get()[0]);
|
||||||
|
uint* dest_current = dest;
|
||||||
|
for (uint i = 0; i < image_size / nComponents; i++)
|
||||||
|
{
|
||||||
|
uint val = *source_current;
|
||||||
|
*dest_current = (val >> 24) | (val << 8); // set alpha (A8) as leftmost byte
|
||||||
|
source_current++;
|
||||||
|
dest_current++;
|
||||||
|
}
|
||||||
|
// NOTE: AppendRawBytes has diff side-effect vs Memory.CopyFromReal
|
||||||
|
data.AppendRawBytes((u8*)dest, image_size);
|
||||||
|
delete[] dest;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
|
|
@ -16,8 +16,8 @@ enum
|
||||||
|
|
||||||
enum CellGifDecStreamSrcSel
|
enum CellGifDecStreamSrcSel
|
||||||
{
|
{
|
||||||
CELL_GIFDEC_FILE = 0, //Input from a file
|
CELL_GIFDEC_FILE = 0, // Input from a file
|
||||||
CELL_GIFDEC_BUFFER = 1, //Input from a buffer
|
CELL_GIFDEC_BUFFER = 1, // Input from a buffer
|
||||||
};
|
};
|
||||||
|
|
||||||
enum CellGifDecColorSpace
|
enum CellGifDecColorSpace
|
||||||
|
@ -105,10 +105,12 @@ struct CellGifDecDataCtrlParam
|
||||||
be_t<u64> outputBytesPerLine;
|
be_t<u64> outputBytesPerLine;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct CellGifDecSubHandle //Custom struct
|
//Custom structs
|
||||||
|
struct CellGifDecSubHandle
|
||||||
{
|
{
|
||||||
u32 fd;
|
u32 fd;
|
||||||
u64 fileSize;
|
u64 fileSize;
|
||||||
CellGifDecInfo info;
|
CellGifDecInfo info;
|
||||||
CellGifDecOutParam outParam;
|
CellGifDecOutParam outParam;
|
||||||
|
CellGifDecSrc src;
|
||||||
};
|
};
|
||||||
|
|
|
@ -33,24 +33,36 @@ int cellJpgDecOpen(u32 mainHandle, mem32_t subHandle, mem_ptr_t<CellJpgDecSrc> s
|
||||||
cellJpgDec->Warning("cellJpgDecOpen(mainHandle=0x%x, subHandle=0x%x, src_addr=0x%x, openInfo=0x%x)",
|
cellJpgDec->Warning("cellJpgDecOpen(mainHandle=0x%x, subHandle=0x%x, src_addr=0x%x, openInfo=0x%x)",
|
||||||
mainHandle, subHandle.GetAddr(), src.GetAddr(), openInfo);
|
mainHandle, subHandle.GetAddr(), src.GetAddr(), openInfo);
|
||||||
|
|
||||||
if (!subHandle.IsGood() || !src.IsGood() || !openInfo.IsGood())
|
if (!subHandle.IsGood() || !src.IsGood())
|
||||||
return CELL_JPGDEC_ERROR_ARG;
|
return CELL_JPGDEC_ERROR_ARG;
|
||||||
|
|
||||||
CellJpgDecSubHandle *current_subHandle = new CellJpgDecSubHandle;
|
CellJpgDecSubHandle *current_subHandle = new CellJpgDecSubHandle;
|
||||||
|
|
||||||
|
current_subHandle->fd = 0;
|
||||||
|
current_subHandle->src = *src;
|
||||||
|
|
||||||
|
switch(src->srcSelect.ToBE())
|
||||||
|
{
|
||||||
|
case se32(CELL_JPGDEC_BUFFER):
|
||||||
|
current_subHandle->fileSize = src->streamSize.ToLE();
|
||||||
|
break;
|
||||||
|
|
||||||
|
case se32(CELL_JPGDEC_FILE):
|
||||||
// Get file descriptor
|
// Get file descriptor
|
||||||
MemoryAllocator<be_t<u32>> fd;
|
MemoryAllocator<be_t<u32>> fd;
|
||||||
int ret = cellFsOpen(src->fileName, 0, fd, 0, 0);
|
int ret = cellFsOpen(src->fileName, 0, fd.GetAddr(), 0, 0);
|
||||||
current_subHandle->fd = fd->ToLE();
|
current_subHandle->fd = fd->ToLE();
|
||||||
if(ret != CELL_OK) return CELL_JPGDEC_ERROR_OPEN_FILE;
|
if (ret != CELL_OK) return CELL_JPGDEC_ERROR_OPEN_FILE;
|
||||||
|
|
||||||
// Get size of file
|
// Get size of file
|
||||||
MemoryAllocator<CellFsStat> sb; // Alloc a CellFsStat struct
|
MemoryAllocator<CellFsStat> sb; // Alloc a CellFsStat struct
|
||||||
ret = cellFsFstat(current_subHandle->fd, sb.GetAddr());
|
ret = cellFsFstat(current_subHandle->fd, sb.GetAddr());
|
||||||
if(ret != CELL_OK) return ret;
|
if (ret != CELL_OK) return ret;
|
||||||
current_subHandle->fileSize = sb->st_size; // Get CellFsStat.st_size
|
current_subHandle->fileSize = sb->st_size; // Get CellFsStat.st_size
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
// From now, every u32 subHandle argument is a pointer to a CellPngDecSubHandle struct.
|
// From now, every u32 subHandle argument is a pointer to a CellJpgDecSubHandle struct.
|
||||||
subHandle = cellJpgDec->GetNewId(current_subHandle);
|
subHandle = cellJpgDec->GetNewId(current_subHandle);
|
||||||
|
|
||||||
return CELL_OK;
|
return CELL_OK;
|
||||||
|
@ -83,12 +95,24 @@ int cellJpgDecReadHeader(u32 mainHandle, u32 subHandle, mem_ptr_t<CellJpgDecInfo
|
||||||
const u64& fileSize = subHandle_data->fileSize;
|
const u64& fileSize = subHandle_data->fileSize;
|
||||||
CellJpgDecInfo& current_info = subHandle_data->info;
|
CellJpgDecInfo& current_info = subHandle_data->info;
|
||||||
|
|
||||||
//Copy the JPG file to a buffer
|
//Write the header to buffer
|
||||||
MemoryAllocator<u8> buffer(fileSize);
|
MemoryAllocator<u8> buffer(fileSize);
|
||||||
MemoryAllocator<be_t<u64>> pos, nread;
|
MemoryAllocator<be_t<u64>> pos, nread;
|
||||||
|
|
||||||
cellFsLseek(fd, 0, CELL_SEEK_SET, pos);
|
switch(subHandle_data->src.srcSelect.ToBE())
|
||||||
|
{
|
||||||
|
case se32(CELL_JPGDEC_BUFFER):
|
||||||
|
if (!Memory.Copy(buffer.GetAddr(), subHandle_data->src.streamPtr.ToLE(), buffer.GetSize())) {
|
||||||
|
cellJpgDec->Error("cellJpgDecReadHeader() failed ()");
|
||||||
|
return CELL_EFAULT;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case se32(CELL_JPGDEC_FILE):
|
||||||
|
cellFsLseek(fd, 0, CELL_SEEK_SET, pos.GetAddr());
|
||||||
cellFsRead(fd, buffer.GetAddr(), buffer.GetSize(), nread);
|
cellFsRead(fd, buffer.GetAddr(), buffer.GetSize(), nread);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
if (*buffer.To<u32>(0) != 0xE0FFD8FF || // Error: Not a valid SOI header
|
if (*buffer.To<u32>(0) != 0xE0FFD8FF || // Error: Not a valid SOI header
|
||||||
*buffer.To<u32>(6) != 0x4649464A) // Error: Not a valid JFIF string
|
*buffer.To<u32>(6) != 0x4649464A) // Error: Not a valid JFIF string
|
||||||
|
@ -146,38 +170,113 @@ int cellJpgDecDecodeData(u32 mainHandle, u32 subHandle, mem8_ptr_t data, const m
|
||||||
//Copy the JPG file to a buffer
|
//Copy the JPG file to a buffer
|
||||||
MemoryAllocator<unsigned char> jpg(fileSize);
|
MemoryAllocator<unsigned char> jpg(fileSize);
|
||||||
MemoryAllocator<u64> pos, nread;
|
MemoryAllocator<u64> pos, nread;
|
||||||
cellFsLseek(fd, 0, CELL_SEEK_SET, pos);
|
|
||||||
cellFsRead(fd, jpg.GetAddr(), jpg.GetSize(), nread);
|
|
||||||
|
|
||||||
//Decode JPG file. (TODO: Is there any faster alternative? Can we do it without external libraries?)
|
switch(subHandle_data->src.srcSelect.ToBE())
|
||||||
int width, height, actual_components;
|
|
||||||
std::shared_ptr<unsigned char> image(stbi_load_from_memory(jpg, fileSize, &width, &height, &actual_components, 4));
|
|
||||||
|
|
||||||
if (!image)
|
|
||||||
return CELL_JPGDEC_ERROR_STREAM_FORMAT;
|
|
||||||
|
|
||||||
uint image_size = width * height;
|
|
||||||
switch((u32)current_outParam.outputColorSpace)
|
|
||||||
{
|
{
|
||||||
case CELL_JPG_RGBA:
|
case se32(CELL_JPGDEC_BUFFER):
|
||||||
case CELL_JPG_RGB:
|
if (!Memory.Copy(jpg.GetAddr(), subHandle_data->src.streamPtr.ToLE(), jpg.GetSize())) {
|
||||||
image_size *= current_outParam.outputColorSpace == CELL_JPG_RGBA ? 4 : 3;
|
cellJpgDec->Error("cellJpgDecDecodeData() failed (I)");
|
||||||
if (!Memory.CopyFromReal(data.GetAddr(), image.get(), image_size))
|
|
||||||
{
|
|
||||||
cellJpgDec->Error("cellJpgDecDecodeData() failed (data_addr=0x%x)", data.GetAddr());
|
|
||||||
return CELL_EFAULT;
|
return CELL_EFAULT;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case CELL_JPG_ARGB:
|
case se32(CELL_JPGDEC_FILE):
|
||||||
image_size *= 4;
|
cellFsLseek(fd, 0, CELL_SEEK_SET, pos.GetAddr());
|
||||||
|
cellFsRead(fd, jpg.GetAddr(), jpg.GetSize(), nread);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
for(u32 i = 0; i < image_size; i+=4)
|
//Decode JPG file. (TODO: Is there any faster alternative? Can we do it without external libraries?)
|
||||||
|
int width, height, actual_components;
|
||||||
|
auto image = std::unique_ptr<unsigned char,decltype(&::free)>
|
||||||
|
(
|
||||||
|
stbi_load_from_memory(jpg.GetPtr(), fileSize, &width, &height, &actual_components, 4),
|
||||||
|
&::free
|
||||||
|
);
|
||||||
|
|
||||||
|
if (!image)
|
||||||
|
return CELL_JPGDEC_ERROR_STREAM_FORMAT;
|
||||||
|
|
||||||
|
const bool flip = current_outParam.outputMode == CELL_JPGDEC_BOTTOM_TO_TOP;
|
||||||
|
const int bytesPerLine = dataCtrlParam->outputBytesPerLine;
|
||||||
|
size_t image_size = width * height;
|
||||||
|
|
||||||
|
switch((u32)current_outParam.outputColorSpace)
|
||||||
{
|
{
|
||||||
data += image.get()[i+3];
|
case CELL_JPG_RGB:
|
||||||
data += image.get()[i+0];
|
case CELL_JPG_RGBA:
|
||||||
data += image.get()[i+1];
|
{
|
||||||
data += image.get()[i+2];
|
const char nComponents = current_outParam.outputColorSpace == CELL_JPG_RGBA ? 4 : 3;
|
||||||
|
image_size *= nComponents;
|
||||||
|
if (bytesPerLine > width * nComponents || flip) //check if we need padding
|
||||||
|
{
|
||||||
|
const int linesize = std::min(bytesPerLine, width * nComponents);
|
||||||
|
for (int i = 0; i < height; i++)
|
||||||
|
{
|
||||||
|
const int dstOffset = i * bytesPerLine;
|
||||||
|
const int srcOffset = width * nComponents * (flip ? height - i - 1 : i);
|
||||||
|
if (!Memory.CopyFromReal(data.GetAddr() + dstOffset, &image.get()[srcOffset], linesize))
|
||||||
|
{
|
||||||
|
cellJpgDec->Error("cellJpgDecDecodeData() failed (II)");
|
||||||
|
return CELL_EFAULT;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (!Memory.CopyFromReal(data.GetAddr(), image.get(), image_size))
|
||||||
|
{
|
||||||
|
cellJpgDec->Error("cellJpgDecDecodeData() failed (III)");
|
||||||
|
return CELL_EFAULT;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case CELL_JPG_ARGB:
|
||||||
|
{
|
||||||
|
const int nComponents = 4;
|
||||||
|
image_size *= nComponents;
|
||||||
|
if (bytesPerLine > width * nComponents || flip) //check if we need padding
|
||||||
|
{
|
||||||
|
//TODO: Find out if we can't do padding without an extra copy
|
||||||
|
const int linesize = std::min(bytesPerLine, width * nComponents);
|
||||||
|
char *output = (char *) malloc(linesize);
|
||||||
|
for (int i = 0; i < height; i++)
|
||||||
|
{
|
||||||
|
const int dstOffset = i * bytesPerLine;
|
||||||
|
const int srcOffset = width * nComponents * (flip ? height - i - 1 : i);
|
||||||
|
for (int j = 0; j < linesize; j += nComponents)
|
||||||
|
{
|
||||||
|
output[j + 0] = image.get()[srcOffset + j + 3];
|
||||||
|
output[j + 1] = image.get()[srcOffset + j + 0];
|
||||||
|
output[j + 2] = image.get()[srcOffset + j + 1];
|
||||||
|
output[j + 3] = image.get()[srcOffset + j + 2];
|
||||||
|
}
|
||||||
|
if (!Memory.CopyFromReal(data.GetAddr() + dstOffset, output, linesize))
|
||||||
|
{
|
||||||
|
cellJpgDec->Error("cellJpgDecDecodeData() failed (IV)");
|
||||||
|
return CELL_EFAULT;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
free(output);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
uint* dest = (uint*)new char[image_size];
|
||||||
|
uint* source_current = (uint*)&(image.get()[0]);
|
||||||
|
uint* dest_current = dest;
|
||||||
|
for (uint i = 0; i < image_size / nComponents; i++)
|
||||||
|
{
|
||||||
|
uint val = *source_current;
|
||||||
|
*dest_current = (val >> 24) | (val << 8); // set alpha (A8) as leftmost byte
|
||||||
|
source_current++;
|
||||||
|
dest_current++;
|
||||||
|
}
|
||||||
|
// NOTE: AppendRawBytes has diff side-effect vs Memory.CopyFromReal
|
||||||
|
data.AppendRawBytes((u8*)dest, image_size);
|
||||||
|
delete[] dest;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
|
|
@ -27,10 +27,22 @@ enum CellJpgDecColorSpace
|
||||||
CELL_JPG_GRAYSCALE_TO_ALPHA_ARGB = 41,
|
CELL_JPG_GRAYSCALE_TO_ALPHA_ARGB = 41,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
enum CellJpgDecStreamSrcSel
|
||||||
|
{
|
||||||
|
CELL_JPGDEC_FILE = 0,
|
||||||
|
CELL_JPGDEC_BUFFER = 1,
|
||||||
|
};
|
||||||
|
|
||||||
enum CellJpgDecDecodeStatus
|
enum CellJpgDecDecodeStatus
|
||||||
{
|
{
|
||||||
CELL_JPGDEC_DEC_STATUS_FINISH = 0, //Decoding finished
|
CELL_JPGDEC_DEC_STATUS_FINISH = 0, // Decoding finished
|
||||||
CELL_JPGDEC_DEC_STATUS_STOP = 1, //Decoding halted
|
CELL_JPGDEC_DEC_STATUS_STOP = 1, // Decoding halted
|
||||||
|
};
|
||||||
|
|
||||||
|
enum CellJpgDecOutputMode
|
||||||
|
{
|
||||||
|
CELL_JPGDEC_TOP_TO_BOTTOM = 0, // Top left to bottom right
|
||||||
|
CELL_JPGDEC_BOTTOM_TO_TOP = 1, // Bottom left to top right
|
||||||
};
|
};
|
||||||
|
|
||||||
struct CellJpgDecInfo
|
struct CellJpgDecInfo
|
||||||
|
@ -92,10 +104,12 @@ struct CellJpgDecDataOutInfo
|
||||||
be_t<u32> status;
|
be_t<u32> status;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct CellJpgDecSubHandle //Custom struct
|
// Custom structs
|
||||||
|
struct CellJpgDecSubHandle
|
||||||
{
|
{
|
||||||
u32 fd;
|
u32 fd;
|
||||||
u64 fileSize;
|
u64 fileSize;
|
||||||
CellJpgDecInfo info;
|
CellJpgDecInfo info;
|
||||||
CellJpgDecOutParam outParam;
|
CellJpgDecOutParam outParam;
|
||||||
|
CellJpgDecSrc src;
|
||||||
};
|
};
|
|
@ -60,7 +60,6 @@ int cellPngDecOpen(u32 mainHandle, mem32_t subHandle, mem_ptr_t<CellPngDecSrc> s
|
||||||
return CELL_PNGDEC_ERROR_ARG;
|
return CELL_PNGDEC_ERROR_ARG;
|
||||||
|
|
||||||
CellPngDecSubHandle *current_subHandle = new CellPngDecSubHandle;
|
CellPngDecSubHandle *current_subHandle = new CellPngDecSubHandle;
|
||||||
|
|
||||||
current_subHandle->fd = 0;
|
current_subHandle->fd = 0;
|
||||||
current_subHandle->src = *src;
|
current_subHandle->src = *src;
|
||||||
|
|
||||||
|
@ -212,16 +211,16 @@ int cellPngDecDecodeData(u32 mainHandle, u32 subHandle, mem8_ptr_t data, const m
|
||||||
MemoryAllocator<unsigned char> png(fileSize);
|
MemoryAllocator<unsigned char> png(fileSize);
|
||||||
MemoryAllocator<u64> pos, nread;
|
MemoryAllocator<u64> pos, nread;
|
||||||
|
|
||||||
switch(subHandle_data->src.srcSelect.ToLE())
|
switch(subHandle_data->src.srcSelect.ToBE())
|
||||||
{
|
|
||||||
case CELL_PNGDEC_BUFFER:
|
|
||||||
if (!Memory.Copy(png.GetAddr(), subHandle_data->src.streamPtr.ToLE(), png.GetSize()))
|
|
||||||
{
|
{
|
||||||
|
case se32(CELL_PNGDEC_BUFFER):
|
||||||
|
if (!Memory.Copy(png.GetAddr(), subHandle_data->src.streamPtr.ToLE(), png.GetSize())) {
|
||||||
cellPngDec->Error("cellPngDecDecodeData() failed (I)");
|
cellPngDec->Error("cellPngDecDecodeData() failed (I)");
|
||||||
return CELL_EFAULT;
|
return CELL_EFAULT;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case CELL_PNGDEC_FILE:
|
|
||||||
|
case se32(CELL_PNGDEC_FILE):
|
||||||
cellFsLseek(fd, 0, CELL_SEEK_SET, pos.GetAddr());
|
cellFsLseek(fd, 0, CELL_SEEK_SET, pos.GetAddr());
|
||||||
cellFsRead(fd, png.GetAddr(), png.GetSize(), nread.GetAddr());
|
cellFsRead(fd, png.GetAddr(), png.GetSize(), nread.GetAddr());
|
||||||
break;
|
break;
|
||||||
|
@ -238,12 +237,11 @@ int cellPngDecDecodeData(u32 mainHandle, u32 subHandle, mem8_ptr_t data, const m
|
||||||
|
|
||||||
const bool flip = current_outParam.outputMode == CELL_PNGDEC_BOTTOM_TO_TOP;
|
const bool flip = current_outParam.outputMode == CELL_PNGDEC_BOTTOM_TO_TOP;
|
||||||
const int bytesPerLine = dataCtrlParam->outputBytesPerLine;
|
const int bytesPerLine = dataCtrlParam->outputBytesPerLine;
|
||||||
|
|
||||||
uint image_size = width * height;
|
uint image_size = width * height;
|
||||||
|
|
||||||
switch((u32)current_outParam.outputColorSpace)
|
switch((u32)current_outParam.outputColorSpace)
|
||||||
{
|
{
|
||||||
case CELL_PNGDEC_RGB:
|
case CELL_PNGDEC_RGB:
|
||||||
image_size = width * height;
|
|
||||||
case CELL_PNGDEC_RGBA:
|
case CELL_PNGDEC_RGBA:
|
||||||
{
|
{
|
||||||
const char nComponents = current_outParam.outputColorSpace == CELL_PNGDEC_RGBA ? 4 : 3;
|
const char nComponents = current_outParam.outputColorSpace == CELL_PNGDEC_RGBA ? 4 : 3;
|
||||||
|
|
|
@ -49,6 +49,7 @@ enum CellPngDecOutputMode
|
||||||
CELL_PNGDEC_BOTTOM_TO_TOP = 1,
|
CELL_PNGDEC_BOTTOM_TO_TOP = 1,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
// Structs
|
// Structs
|
||||||
struct CellPngDecDataOutInfo
|
struct CellPngDecDataOutInfo
|
||||||
{
|
{
|
||||||
|
@ -108,23 +109,6 @@ struct CellPngDecOutParam
|
||||||
be_t<u32> useMemorySpace;
|
be_t<u32> useMemorySpace;
|
||||||
};
|
};
|
||||||
|
|
||||||
//Custom structs
|
|
||||||
struct CellPngDecSubHandle
|
|
||||||
{
|
|
||||||
be_t<u32> fd;
|
|
||||||
be_t<u64> fileSize;
|
|
||||||
CellPngDecInfo info;
|
|
||||||
CellPngDecOutParam outParam;
|
|
||||||
CellPngDecSrc src;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct CellPngDecMainHandle
|
|
||||||
{
|
|
||||||
be_t<u32> mainHandle;
|
|
||||||
be_t<u32> threadInParam;
|
|
||||||
be_t<u32> threadOutParam;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct CellPngDecStrmInfo
|
struct CellPngDecStrmInfo
|
||||||
{
|
{
|
||||||
be_t<u32> decodedStrmSize;
|
be_t<u32> decodedStrmSize;
|
||||||
|
@ -175,3 +159,21 @@ struct CellPngDecOpnParam
|
||||||
{
|
{
|
||||||
be_t<u32> selectChunk;
|
be_t<u32> selectChunk;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
// Custom structs
|
||||||
|
struct CellPngDecSubHandle
|
||||||
|
{
|
||||||
|
be_t<u32> fd;
|
||||||
|
be_t<u64> fileSize;
|
||||||
|
CellPngDecInfo info;
|
||||||
|
CellPngDecOutParam outParam;
|
||||||
|
CellPngDecSrc src;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct CellPngDecMainHandle
|
||||||
|
{
|
||||||
|
be_t<u32> mainHandle;
|
||||||
|
be_t<u32> threadInParam;
|
||||||
|
be_t<u32> threadOutParam;
|
||||||
|
};
|
||||||
|
|
|
@ -206,12 +206,14 @@ void GameViewer::DClick(wxListEvent& event)
|
||||||
Emu.Stop();
|
Emu.Stop();
|
||||||
Emu.GetVFS().Init(path);
|
Emu.GetVFS().Init(path);
|
||||||
std::string local_path;
|
std::string local_path;
|
||||||
if(Emu.GetVFS().GetDevice(path, local_path) && !Emu.BootGame(local_path))
|
if (Emu.GetVFS().GetDevice(path, local_path) && !Emu.BootGame(local_path)) {
|
||||||
{
|
|
||||||
LOG_ERROR(HLE, "Boot error: elf not found! [%s]", path.c_str());
|
LOG_ERROR(HLE, "Boot error: elf not found! [%s]", path.c_str());
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (Ini.HLEAlwaysStart.GetValue() && Emu.IsReady()) {
|
||||||
Emu.Run();
|
Emu.Run();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void GameViewer::RightClick(wxListEvent& event)
|
void GameViewer::RightClick(wxListEvent& event)
|
||||||
|
|
|
@ -40,10 +40,8 @@ enum IDs
|
||||||
id_tools_compiler,
|
id_tools_compiler,
|
||||||
id_tools_memory_viewer,
|
id_tools_memory_viewer,
|
||||||
id_tools_rsx_debugger,
|
id_tools_rsx_debugger,
|
||||||
id_tools_fnid_generator,
|
|
||||||
id_help_about,
|
id_help_about,
|
||||||
id_update_dbg,
|
id_update_dbg,
|
||||||
id_boot_game_and_run,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
wxString GetPaneName()
|
wxString GetPaneName()
|
||||||
|
@ -69,11 +67,10 @@ MainFrame::MainFrame()
|
||||||
|
|
||||||
wxMenu* menu_boot = new wxMenu();
|
wxMenu* menu_boot = new wxMenu();
|
||||||
menubar->Append(menu_boot, "Boot");
|
menubar->Append(menu_boot, "Boot");
|
||||||
|
menu_boot->Append(id_boot_elf, "Boot ELF / SELF file");
|
||||||
menu_boot->Append(id_boot_game, "Boot game");
|
menu_boot->Append(id_boot_game, "Boot game");
|
||||||
menu_boot->Append(id_boot_game_and_run, "Boot game and start");
|
|
||||||
menu_boot->Append(id_install_pkg, "Install PKG");
|
|
||||||
menu_boot->AppendSeparator();
|
menu_boot->AppendSeparator();
|
||||||
menu_boot->Append(id_boot_elf, "Boot (S)ELF");
|
menu_boot->Append(id_install_pkg, "Install PKG");
|
||||||
|
|
||||||
wxMenu* menu_sys = new wxMenu();
|
wxMenu* menu_sys = new wxMenu();
|
||||||
menubar->Append(menu_sys, "System");
|
menubar->Append(menu_sys, "System");
|
||||||
|
@ -113,10 +110,9 @@ MainFrame::MainFrame()
|
||||||
AddPane(m_debugger_frame, "Debugger", wxAUI_DOCK_RIGHT);
|
AddPane(m_debugger_frame, "Debugger", wxAUI_DOCK_RIGHT);
|
||||||
|
|
||||||
// Events
|
// Events
|
||||||
Bind(wxEVT_MENU, &MainFrame::BootGame, this, id_boot_game);
|
|
||||||
Bind(wxEVT_MENU, &MainFrame::BootGameAndRun, this, id_boot_game_and_run);
|
|
||||||
Bind(wxEVT_MENU, &MainFrame::InstallPkg, this, id_install_pkg);
|
|
||||||
Bind(wxEVT_MENU, &MainFrame::BootElf, this, id_boot_elf);
|
Bind(wxEVT_MENU, &MainFrame::BootElf, this, id_boot_elf);
|
||||||
|
Bind(wxEVT_MENU, &MainFrame::BootGame, this, id_boot_game);
|
||||||
|
Bind(wxEVT_MENU, &MainFrame::InstallPkg, this, id_install_pkg);
|
||||||
|
|
||||||
Bind(wxEVT_MENU, &MainFrame::Pause, this, id_sys_pause);
|
Bind(wxEVT_MENU, &MainFrame::Pause, this, id_sys_pause);
|
||||||
Bind(wxEVT_MENU, &MainFrame::Stop, this, id_sys_stop);
|
Bind(wxEVT_MENU, &MainFrame::Stop, this, id_sys_stop);
|
||||||
|
@ -201,40 +197,6 @@ void MainFrame::BootGame(wxCommandEvent& WXUNUSED(event))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void MainFrame::BootGameAndRun(wxCommandEvent& WXUNUSED(event))
|
|
||||||
{
|
|
||||||
bool stopped = false;
|
|
||||||
|
|
||||||
if (Emu.IsRunning())
|
|
||||||
{
|
|
||||||
Emu.Pause();
|
|
||||||
stopped = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
wxDirDialog ctrl(this, L"Select game folder", wxEmptyString);
|
|
||||||
|
|
||||||
if (ctrl.ShowModal() == wxID_CANCEL)
|
|
||||||
{
|
|
||||||
if (stopped) Emu.Resume();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
Emu.Stop();
|
|
||||||
|
|
||||||
if (Emu.BootGame(ctrl.GetPath().ToStdString()))
|
|
||||||
{
|
|
||||||
LOG_SUCCESS(HLE, "Game: boot done.");
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
LOG_ERROR(HLE, "PS3 executable not found in selected folder (%s)", ctrl.GetPath().wx_str());
|
|
||||||
}
|
|
||||||
|
|
||||||
if (Emu.IsReady())
|
|
||||||
{
|
|
||||||
Emu.Run();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
void MainFrame::InstallPkg(wxCommandEvent& WXUNUSED(event))
|
void MainFrame::InstallPkg(wxCommandEvent& WXUNUSED(event))
|
||||||
{
|
{
|
||||||
bool stopped = false;
|
bool stopped = false;
|
||||||
|
@ -299,7 +261,6 @@ void MainFrame::BootElf(wxCommandEvent& WXUNUSED(event))
|
||||||
LOG_NOTICE(HLE, "(S)ELF: booting...");
|
LOG_NOTICE(HLE, "(S)ELF: booting...");
|
||||||
|
|
||||||
Emu.Stop();
|
Emu.Stop();
|
||||||
|
|
||||||
Emu.SetPath(fmt::ToUTF8(ctrl.GetPath()));
|
Emu.SetPath(fmt::ToUTF8(ctrl.GetPath()));
|
||||||
Emu.Load();
|
Emu.Load();
|
||||||
|
|
||||||
|
|
|
@ -276,7 +276,7 @@ public:
|
||||||
HLESaveTTY.Load(false);
|
HLESaveTTY.Load(false);
|
||||||
HLEExitOnStop.Load(false);
|
HLEExitOnStop.Load(false);
|
||||||
HLELogLvl.Load(3);
|
HLELogLvl.Load(3);
|
||||||
HLEAlwaysStart.Load(false);
|
HLEAlwaysStart.Load(true);
|
||||||
|
|
||||||
// Language
|
// Language
|
||||||
SysLanguage.Load(1);
|
SysLanguage.Load(1);
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue