int cellFsStReadInit(u32 fd, mem_ptr_t<CellFsRingBuffer> ringbuf) { sys_fs.Warning("cellFsStReadInit(fd=%d, ringbuf_addr=0x%x)", fd, ringbuf.GetAddr()); vfsStream* file; if(!sys_fs.CheckId(fd, file)) return CELL_ESRCH; if(!ringbuf.IsGood()) return CELL_EFAULT; FsRingBuffer& buffer = m_fs_config.m_ring_buffer; buffer.m_block_size = ringbuf->block_size; buffer.m_copy = ringbuf->copy; buffer.m_ringbuf_size = ringbuf->ringbuf_size; buffer.m_transfer_rate = ringbuf->transfer_rate; if(buffer.m_ringbuf_size < 0x40000000) // If the size is less than 1MB m_fs_config.m_alloc_mem_size = ((ringbuf->ringbuf_size + 64 * 1024 - 1) / (64 * 1024)) * (64 * 1024); m_fs_config.m_alloc_mem_size = ((ringbuf->ringbuf_size + 1024 * 1024 - 1) / (1024 * 1024)) * (1024 * 1024); // alloc memory m_fs_config.m_buffer = Memory.Alloc(m_fs_config.m_alloc_mem_size, 1024); memset(Memory + m_fs_config.m_buffer, 0, m_fs_config.m_alloc_mem_size); m_fs_config.m_fs_status = CELL_FS_ST_INITIALIZED; return CELL_OK; }
int cellFsFtruncate(u32 fd, u64 size) { sys_fs.Log("cellFsFtruncate(fd=%d, size=%lld)", fd, size); u32 attr; vfsStream* file; if(!sys_fs.CheckId(fd, file, attr) || attr != IDFlag_File) return CELL_ESRCH; u64 initialSize = file->GetSize(); if (initialSize < size) { u64 last_pos = file->Tell(); file->Seek(0, vfsSeekEnd); static const char nullbyte = 0; file->Seek(size-initialSize-1, vfsSeekCur); file->Write(&nullbyte, sizeof(char)); file->Seek(last_pos, vfsSeekSet); } if (initialSize > size) { // (TODO) } return CELL_OK; }
int cellFsReaddir(u32 fd, mem_ptr_t<CellFsDirent> dir, mem64_t nread) { sys_fs.Log("cellFsReaddir(fd=%d, dir_addr=0x%x, nread_addr=0x%x)", fd, dir.GetAddr(), nread.GetAddr()); vfsDirBase* directory; if(!sys_fs.CheckId(fd, directory)) return CELL_ESRCH; if(!dir.IsGood() || !nread.IsGood()) return CELL_EFAULT; const DirEntryInfo* info = directory->Read(); if(info) { nread = 1; Memory.WriteString(dir.GetAddr()+2, info->name.wx_str()); dir->d_namlen = info->name.Length(); dir->d_type = (info->flags & DirEntry_TypeFile) ? CELL_FS_TYPE_REGULAR : CELL_FS_TYPE_DIRECTORY; } else { nread = 0; } return CELL_OK; }
int cellPngDecDecodeData(u32 mainHandle, u32 subHandle, mem8_ptr_t data, const mem_struct_ptr_t<CellPngDecDataCtrlParam> dataCtrlParam, mem_struct_ptr_t<CellPngDecDataOutInfo> dataOutInfo) { dataOutInfo->status = CELL_PNGDEC_DEC_STATUS_STOP; ID sub_handle_id_data; if(!cellPngDec.CheckId(subHandle, sub_handle_id_data)) return CELL_PNGDEC_ERROR_FATAL; auto subHandle_data = (CellPngDecSubHandle*)sub_handle_id_data.m_data; const u32& fd = subHandle_data->fd; const u64& fileSize = subHandle_data->fileSize; const CellPngDecOutParam& current_outParam = subHandle_data->outParam; //Copy the PNG file to a buffer MemoryAllocator<unsigned char> png(fileSize); MemoryAllocator<u64> pos, nread; cellFsLseek(fd, 0, CELL_SEEK_SET, pos); cellFsRead(fd, png.GetAddr(), png.GetSize(), nread); //Decode PNG file. (TODO: Is there any faster alternative? Can we do it without external libraries?) int width, height, actual_components; std::shared_ptr<unsigned char> image(stbi_load_from_memory(png, fileSize, &width, &height, &actual_components, 4)); if (!image) return CELL_PNGDEC_ERROR_STREAM_FORMAT; uint image_size = width * height; switch(current_outParam.outputColorSpace) { case CELL_PNGDEC_RGB: case CELL_PNGDEC_RGBA: image_size *= current_outParam.outputColorSpace == CELL_PNGDEC_RGBA ? 4 : 3; memcpy(data, image.get(), image_size); break; case CELL_PNGDEC_ARGB: image_size *= 4; for(uint i = 0; i < image_size; i+=4) { data += image.get()[i+3]; data += image.get()[i+0]; data += image.get()[i+1]; data += image.get()[i+2]; } break; case CELL_PNGDEC_GRAYSCALE: case CELL_PNGDEC_PALETTE: case CELL_PNGDEC_GRAYSCALE_ALPHA: cellPngDec.Error("cellPngDecDecodeData: Unsupported color space (%d)", current_outParam.outputColorSpace.ToLE()); break; default: return CELL_PNGDEC_ERROR_ARG; } dataOutInfo->status = CELL_PNGDEC_DEC_STATUS_FINISH; return CELL_OK; }
int cellPngDecReadHeader(u32 mainHandle, u32 subHandle, mem_ptr_t<CellPngDecInfo> info) { if (!info.IsGood()) return CELL_PNGDEC_ERROR_ARG; cellPngDec.Warning("cellPngDecReadHeader(mainHandle=0x%x, subHandle=0x%x, info_addr=0x%llx)", mainHandle, subHandle, info.GetAddr()); CellPngDecSubHandle* subHandle_data; if(!cellPngDec.CheckId(subHandle, subHandle_data)) return CELL_PNGDEC_ERROR_FATAL; const u32& fd = subHandle_data->fd; const u64& fileSize = subHandle_data->fileSize; CellPngDecInfo& current_info = subHandle_data->info; //Check size of file if(fileSize < 29) return CELL_PNGDEC_ERROR_HEADER; // Error: The file is smaller than the length of a PNG header //Write the header to buffer MemoryAllocator<be_t<u32>> buffer(34); // Alloc buffer for PNG header MemoryAllocator<be_t<u64>> pos, nread; switch(subHandle_data->src.srcSelect.ToLE()) { case CELL_PNGDEC_BUFFER: Memory.Copy(buffer.GetAddr(), subHandle_data->src.streamPtr.ToLE(), buffer.GetSize()); break; case CELL_PNGDEC_FILE: cellFsLseek(fd, 0, CELL_SEEK_SET, pos.GetAddr()); cellFsRead(fd, buffer.GetAddr(), buffer.GetSize(), nread.GetAddr()); break; } if (buffer[0] != 0x89504E47 || buffer[1] != 0x0D0A1A0A || // Error: The first 8 bytes are not a valid PNG signature buffer[3] != 0x49484452) // Error: The PNG file does not start with an IHDR chunk { return CELL_PNGDEC_ERROR_HEADER; } switch (buffer.To<u8>()[25]) { case 0: current_info.colorSpace = CELL_PNGDEC_GRAYSCALE; current_info.numComponents = 1; break; case 2: current_info.colorSpace = CELL_PNGDEC_RGB; current_info.numComponents = 3; break; case 3: current_info.colorSpace = CELL_PNGDEC_PALETTE; current_info.numComponents = 1; break; case 4: current_info.colorSpace = CELL_PNGDEC_GRAYSCALE_ALPHA; current_info.numComponents = 2; break; case 6: current_info.colorSpace = CELL_PNGDEC_RGBA; current_info.numComponents = 4; break; default: return CELL_PNGDEC_ERROR_HEADER; // Not supported color type } current_info.imageWidth = buffer[4]; current_info.imageHeight = buffer[5]; current_info.bitDepth = buffer.To<u8>()[24]; current_info.interlaceMethod = buffer.To<u8>()[28]; current_info.chunkInformation = 0; // Unimplemented *info = current_info; return CELL_OK; }
int cellJpgDecReadHeader(u32 mainHandle, u32 subHandle, mem_struct_ptr_t<CellJpgDecInfo> info) { cellJpgDec.Log("cellJpgDecReadHeader(mainHandle=0x%x, subHandle=0x%x, info_addr=0x%llx)", mainHandle, subHandle, info.GetAddr()); ID sub_handle_id_data; if(!cellJpgDec.CheckId(subHandle, sub_handle_id_data)) return CELL_JPGDEC_ERROR_FATAL; auto subHandle_data = (CellJpgDecSubHandle*)sub_handle_id_data.m_data; const u32& fd = subHandle_data->fd; const u64& fileSize = subHandle_data->fileSize; CellJpgDecInfo& current_info = subHandle_data->info; //Copy the JPG file to a buffer MemoryAllocator<u8> buffer(fileSize); MemoryAllocator<be_t<u64>> pos, nread; cellFsLseek(fd, 0, CELL_SEEK_SET, pos); cellFsRead(fd, buffer.GetAddr(), buffer.GetSize(), nread); if (*buffer.To<u32>(0) != 0xE0FFD8FF || // Error: Not a valid SOI header *buffer.To<u32>(6) != 0x4649464A) // Error: Not a valid JFIF string { return CELL_JPGDEC_ERROR_HEADER; } u32 i = 4; if(i >= fileSize) return CELL_JPGDEC_ERROR_HEADER; u16 block_length = buffer[i] * 0xFF + buffer[i+1]; while(true) { i += block_length; // Increase the file index to get to the next block if (i >= fileSize || // Check to protect against segmentation faults buffer[i] != 0xFF) // Check that we are truly at the start of another block { return CELL_JPGDEC_ERROR_HEADER; } if(buffer[i+1] == 0xC0) break; // 0xFFC0 is the "Start of frame" marker which contains the file size i += 2; // Skip the block marker block_length = buffer[i] * 0xFF + buffer[i+1]; // Go to the next block } current_info.imageWidth = buffer[i+7]*0x100 + buffer[i+8]; current_info.imageHeight = buffer[i+5]*0x100 + buffer[i+6]; current_info.numComponents = 3; // Unimplemented current_info.colorSpace = CELL_JPG_RGB; info = current_info; return CELL_OK; }
int cellFsStReadWait(u32 fd, u64 size) { sys_fs.Warning("TODO: cellFsStReadWait(fd=%d, size = 0x%llx)", fd, size); vfsStream* file; if(!sys_fs.CheckId(fd, file)) return CELL_ESRCH; return CELL_OK; }
int cellFsStReadGetRegid(u32 fd, mem64_t regid) { sys_fs.Warning("cellFsStReadGetRingBuf(fd=%d, regid_addr=0x%x)", fd, regid.GetAddr()); vfsStream* file; if(!sys_fs.CheckId(fd, file)) return CELL_ESRCH; regid = m_fs_config.m_regid; return CELL_OK; }
int cellFsStReadStop(u32 fd) { sys_fs.Warning("cellFsStReadStop(fd=%d)", fd); vfsStream* file; if(!sys_fs.CheckId(fd, file)) return CELL_ESRCH; m_fs_config.m_fs_status = CELL_FS_ST_STOP; return CELL_OK; }
int cellJpgDecClose(u32 mainHandle, u32 subHandle) { CellJpgDecSubHandle* subHandle_data; if(!cellJpgDec.CheckId(subHandle, subHandle_data)) return CELL_JPGDEC_ERROR_FATAL; cellFsClose(subHandle_data->fd); Emu.GetIdManager().RemoveID(subHandle); return CELL_OK; }
int cellFsStReadGetCurrentAddr(u32 fd, mem32_t addr_addr, mem64_t size) { sys_fs.Warning("TODO: cellFsStReadGetCurrentAddr(fd=%d, addr_addr=0x%x, size_addr = 0x%x)", fd, addr_addr.GetAddr(), size.GetAddr()); vfsStream* file; if(!sys_fs.CheckId(fd, file)) return CELL_ESRCH; if (!addr_addr.IsGood() && !size.IsGood()) return CELL_EFAULT; return CELL_OK; }
int cellFsStReadPutCurrentAddr(u32 fd, u32 addr_addr, u64 size) { sys_fs.Warning("TODO: cellFsStReadPutCurrentAddr(fd=%d, addr_addr=0x%x, size = 0x%llx)", fd, addr_addr, size); vfsStream* file; if(!sys_fs.CheckId(fd, file)) return CELL_ESRCH; if (!Memory.IsGoodAddr(addr_addr)) return CELL_EFAULT; return CELL_OK; }
int cellFsStReadGetStatus(u32 fd, mem64_t status) { sys_fs.Warning("cellFsStReadGetRingBuf(fd=%d, status_addr=0x%x)", fd, status.GetAddr()); vfsStream* file; if(!sys_fs.CheckId(fd, file)) return CELL_ESRCH; status = m_fs_config.m_fs_status; return CELL_OK; }
int cellGifDecDecodeData(u32 mainHandle, u32 subHandle, mem8_ptr_t data, const mem_ptr_t<CellGifDecDataCtrlParam> dataCtrlParam, mem_ptr_t<CellGifDecDataOutInfo> dataOutInfo) { if (!data.IsGood() || !dataCtrlParam.IsGood() || !dataOutInfo.IsGood()) return CELL_GIFDEC_ERROR_ARG; dataOutInfo->status = CELL_GIFDEC_DEC_STATUS_STOP; CellGifDecSubHandle* subHandle_data; if(!cellGifDec.CheckId(subHandle, subHandle_data)) return CELL_GIFDEC_ERROR_FATAL; const u32& fd = subHandle_data->fd; const u64& fileSize = subHandle_data->fileSize; const CellGifDecOutParam& current_outParam = subHandle_data->outParam; //Copy the GIF file to a buffer MemoryAllocator<unsigned char> gif(fileSize); 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?) 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(current_outParam.outputColorSpace) { case CELL_GIFDEC_RGBA: Memory.CopyFromReal(data.GetAddr(), image.get(), image_size); break; case CELL_GIFDEC_ARGB: for(uint i = 0; i < image_size; i+=4) { data += image.get()[i+3]; data += image.get()[i+0]; data += image.get()[i+1]; data += image.get()[i+2]; } break; default: return CELL_GIFDEC_ERROR_ARG; } dataOutInfo->status = CELL_GIFDEC_DEC_STATUS_FINISH; dataOutInfo->recordType = CELL_GIFDEC_RECORD_TYPE_IMAGE_DESC; return CELL_OK; }
int cellFsStReadWaitCallback(u32 fd, u64 size, mem_func_ptr_t<void (*)(int xfd, u64 xsize)> func) { sys_fs.Warning("TODO: cellFsStReadWaitCallback(fd=%d, size = 0x%llx, func_addr = 0x%x)", fd, size, func.GetAddr()); if (!func.IsGood()) return CELL_EFAULT; vfsStream* file; if(!sys_fs.CheckId(fd, file)) return CELL_ESRCH; return CELL_OK; }
int cellFsStReadFinish(u32 fd) { sys_fs.Warning("cellFsStReadFinish(fd=%d)", fd); vfsStream* file; if(!sys_fs.CheckId(fd, file)) return CELL_ESRCH; Memory.Free(m_fs_config.m_buffer); m_fs_config.m_fs_status = CELL_FS_ST_NOT_INITIALIZED; return CELL_OK; }
int cellFsStReadStart(u32 fd, u64 offset, u64 size) { sys_fs.Warning("TODO: cellFsStReadStart(fd=%d, offset=0x%llx, size=0x%llx)", fd, offset, size); vfsStream* file; if(!sys_fs.CheckId(fd, file)) return CELL_ESRCH; m_fs_config.m_current_addr = m_fs_config.m_buffer + (u32)offset; m_fs_config.m_fs_status = CELL_FS_ST_PROGRESS; return CELL_OK; }
int cellFsFGetBlockSize(u32 fd, mem64_t sector_size, mem64_t block_size) { sys_fs.Log("cellFsFGetBlockSize(fd=%d, sector_size_addr: 0x%x, block_size_addr: 0x%x)", fd, sector_size.GetAddr(), block_size.GetAddr()); vfsStream* file; if(!sys_fs.CheckId(fd, file)) return CELL_ESRCH; sector_size = 4096; // ? block_size = 4096; // ? return CELL_OK; }
int cellPngDecClose(u32 mainHandle, u32 subHandle) { ID sub_handle_id_data; if(!cellPngDec.CheckId(subHandle, sub_handle_id_data)) return CELL_PNGDEC_ERROR_FATAL; auto subHandle_data = (CellPngDecSubHandle*)sub_handle_id_data.m_data; cellFsClose(subHandle_data->fd); Emu.GetIdManager().RemoveID(subHandle); return CELL_OK; }
int cellPngDecClose(u32 mainHandle, u32 subHandle) { cellPngDec.Warning("cellPngDecClose(mainHandle=0x%x,subHandle=0x%x)", mainHandle, subHandle); CellPngDecSubHandle* subHandle_data; if(!cellPngDec.CheckId(subHandle, subHandle_data)) return CELL_PNGDEC_ERROR_FATAL; cellFsClose(subHandle_data->fd); Emu.GetIdManager().RemoveID(subHandle); return CELL_OK; }
int cellFsStRead(u32 fd, u32 buf_addr, u64 size, mem64_t rsize) { sys_fs.Warning("TODO: cellFsStRead(fd=%d, buf_addr=0x%x, size=0x%llx, rsize_addr = 0x%x)", fd, buf_addr, size, rsize.GetAddr()); vfsStream* file; if(!sys_fs.CheckId(fd, file)) return CELL_ESRCH; if (rsize.GetAddr() && !rsize.IsGood()) return CELL_EFAULT; m_fs_config.m_regid += size; rsize = m_fs_config.m_regid; return CELL_OK; }
int cellFsRead(u32 fd, u32 buf_addr, u64 nbytes, mem64_t nread) { sys_fs.Log("cellFsRead(fd=%d, buf_addr=0x%x, nbytes=0x%llx, nread_addr=0x%x)", fd, buf_addr, nbytes, nread.GetAddr()); vfsStream* file; if(!sys_fs.CheckId(fd, file)) return CELL_ESRCH; if (nread.GetAddr() && !nread.IsGood()) return CELL_EFAULT; u32 res = 0; u32 count = nbytes; if (nbytes != (u64)count) return CELL_ENOMEM; if (!Memory.IsGoodAddr(buf_addr)) return CELL_EFAULT; if (count) if (u32 frag = buf_addr & 4095) // memory page fragment { u32 req = min(count, 4096 - frag); u32 read = file->Read(Memory + buf_addr, req); buf_addr += req; res += read; count -= req; if (read < req) goto fin; } for (u32 pages = count / 4096; pages > 0; pages--) // full pages { if (!Memory.IsGoodAddr(buf_addr)) goto fin; // ??? (probably EFAULT) u32 read = file->Read(Memory + buf_addr, 4096); buf_addr += 4096; res += read; count -= 4096; if (read < 4096) goto fin; } if (count) // last fragment { if (!Memory.IsGoodAddr(buf_addr)) goto fin; res += file->Read(Memory + buf_addr, count); } fin: if (nread.GetAddr()) nread = res; // write value if not NULL return CELL_OK; }
int cellFsLseek(u32 fd, s64 offset, u32 whence, mem64_t pos) { vfsSeekMode seek_mode; sys_fs.Log("cellFsLseek(fd: %d, offset: 0x%llx, whence: %d, pos_addr: 0x%x)", fd, offset, whence, pos.GetAddr()); switch(whence) { case CELL_SEEK_SET: seek_mode = vfsSeekSet; break; case CELL_SEEK_CUR: seek_mode = vfsSeekCur; break; case CELL_SEEK_END: seek_mode = vfsSeekEnd; break; default: sys_fs.Error(fd, "Unknown seek whence! (%d)", whence); return CELL_EINVAL; } vfsStream* file; if(!sys_fs.CheckId(fd, file)) return CELL_ESRCH; pos = file->Seek(offset, seek_mode); return CELL_OK; }
int cellJpgDecSetParameter(u32 mainHandle, u32 subHandle, const mem_ptr_t<CellJpgDecInParam> inParam, mem_ptr_t<CellJpgDecOutParam> outParam) { if (!inParam.IsGood() || !outParam.IsGood()) return CELL_JPGDEC_ERROR_ARG; CellJpgDecSubHandle* subHandle_data; if(!cellJpgDec.CheckId(subHandle, subHandle_data)) return CELL_JPGDEC_ERROR_FATAL; CellJpgDecInfo& current_info = subHandle_data->info; CellJpgDecOutParam& current_outParam = subHandle_data->outParam; current_outParam.outputWidthByte = (current_info.imageWidth * current_info.numComponents); current_outParam.outputWidth = current_info.imageWidth; current_outParam.outputHeight = current_info.imageHeight; current_outParam.outputColorSpace = inParam->outputColorSpace; switch ((u32)current_outParam.outputColorSpace) { case CELL_JPG_GRAYSCALE: current_outParam.outputComponents = 1; break; case CELL_JPG_RGB: case CELL_JPG_YCbCr: current_outParam.outputComponents = 3; break; case CELL_JPG_UPSAMPLE_ONLY: current_outParam.outputComponents = current_info.numComponents; break; case CELL_JPG_RGBA: case CELL_JPG_ARGB: case CELL_JPG_GRAYSCALE_TO_ALPHA_RGBA: case CELL_JPG_GRAYSCALE_TO_ALPHA_ARGB: current_outParam.outputComponents = 4; break; default: return CELL_JPGDEC_ERROR_ARG; // Not supported color space } current_outParam.outputMode = inParam->outputMode; current_outParam.downScale = inParam->downScale; current_outParam.useMemorySpace = 0; // Unimplemented *outParam = current_outParam; return CELL_OK; }
int cellFsRead(u32 fd, u32 buf_addr, u64 nbytes, mem64_t nread) { sys_fs.Log("cellFsRead(fd: %d, buf_addr: 0x%x, nbytes: 0x%llx, nread_addr: 0x%x)", fd, buf_addr, nbytes, nread.GetAddr()); vfsStream* file; if(!sys_fs.CheckId(fd, file)) return CELL_ESRCH; 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()) nread = res; return CELL_OK; }
int cellFsWrite(u32 fd, u32 buf_addr, u64 nbytes, mem64_t nwrite) { sys_fs.Log("cellFsWrite(fd=%d, buf_addr=0x%x, nbytes=0x%llx, nwrite_addr=0x%x)", fd, buf_addr, nbytes, nwrite.GetAddr()); vfsStream* file; if(!sys_fs.CheckId(fd, file)) return CELL_ESRCH; 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->Write(Memory.GetMemFromAddr(buf_addr), nbytes) : 0; if(nwrite.IsGood()) nwrite = res; return CELL_OK; }
int cellFsStReadGetRingBuf(u32 fd, mem_ptr_t<CellFsRingBuffer> ringbuf) { sys_fs.Warning("cellFsStReadGetRingBuf(fd=%d, ringbuf_addr=0x%x)", fd, ringbuf.GetAddr()); vfsStream* file; if(!sys_fs.CheckId(fd, file)) return CELL_ESRCH; if(!ringbuf.IsGood()) return CELL_EFAULT; FsRingBuffer& buffer = m_fs_config.m_ring_buffer; ringbuf->block_size = buffer.m_block_size; ringbuf->copy = buffer.m_copy; ringbuf->ringbuf_size = buffer.m_ringbuf_size; ringbuf->transfer_rate = buffer.m_transfer_rate; sys_fs.Warning("*** fs stream config: block_size=0x%llx, copy=%d, ringbuf_size = 0x%llx, transfer_rate = 0x%llx", ringbuf->block_size, ringbuf->copy, ringbuf->ringbuf_size, ringbuf->transfer_rate); return CELL_OK; }
int cellGifDecReadHeader(u32 mainHandle, u32 subHandle, mem_ptr_t<CellGifDecInfo> info) { if (!info.IsGood()) return CELL_GIFDEC_ERROR_ARG; CellGifDecSubHandle* subHandle_data; if(!cellGifDec.CheckId(subHandle, subHandle_data)) return CELL_GIFDEC_ERROR_FATAL; const u32& fd = subHandle_data->fd; const u64& fileSize = subHandle_data->fileSize; CellGifDecInfo& current_info = subHandle_data->info; //Write the header to buffer MemoryAllocator<u8> buffer(13); // Alloc buffer for GIF header MemoryAllocator<be_t<u64>> pos, nread; cellFsLseek(fd, 0, CELL_SEEK_SET, pos); cellFsRead(fd, buffer.GetAddr(), buffer.GetSize(), nread); 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 { return CELL_GIFDEC_ERROR_STREAM_FORMAT; // Surprisingly there is no error code related with headerss } u8 packedField = buffer[10]; current_info.SWidth = buffer[6] + buffer[7] * 0x100; current_info.SHeight = buffer[8] + buffer[9] * 0x100; current_info.SGlobalColorTableFlag = packedField >> 7; current_info.SColorResolution = ((packedField >> 4) & 7)+1; current_info.SSortFlag = (packedField >> 3) & 1; current_info.SSizeOfGlobalColorTable = (packedField & 7)+1; current_info.SBackGroundColor = buffer[11]; current_info.SPixelAspectRatio = buffer[12]; *info = current_info; return CELL_OK; }
int cellPngDecSetParameter(u32 mainHandle, u32 subHandle, const mem_struct_ptr_t<CellPngDecInParam> inParam, mem_struct_ptr_t<CellPngDecOutParam> outParam) { ID sub_handle_id_data; if(!cellPngDec.CheckId(subHandle, sub_handle_id_data)) return CELL_PNGDEC_ERROR_FATAL; auto subHandle_data = (CellPngDecSubHandle*)sub_handle_id_data.m_data; CellPngDecInfo& current_info = subHandle_data->info; CellPngDecOutParam& current_outParam = subHandle_data->outParam; current_outParam.outputWidthByte = (current_info.imageWidth * current_info.numComponents * current_info.bitDepth) / 8; current_outParam.outputWidth = current_info.imageWidth; current_outParam.outputHeight = current_info.imageHeight; current_outParam.outputColorSpace = inParam->outputColorSpace; switch (current_outParam.outputColorSpace) { case CELL_PNGDEC_PALETTE: case CELL_PNGDEC_GRAYSCALE: current_outParam.outputComponents = 1; break; case CELL_PNGDEC_GRAYSCALE_ALPHA: current_outParam.outputComponents = 2; break; case CELL_PNGDEC_RGB: current_outParam.outputComponents = 3; break; case CELL_PNGDEC_RGBA: case CELL_PNGDEC_ARGB: current_outParam.outputComponents = 4; break; default: return CELL_PNGDEC_ERROR_ARG; // Not supported color space } current_outParam.outputBitDepth = inParam->outputBitDepth; current_outParam.outputMode = inParam->outputMode; current_outParam.useMemorySpace = 0; // Unimplemented outParam = current_outParam; return CELL_OK; }
int cellFsFstat(u32 fd, mem_ptr_t<CellFsStat> sb) { sys_fs.Log("cellFsFstat(fd: %d, sb_addr: 0x%x)", fd, sb.GetAddr()); vfsStream* file; if(!sys_fs.CheckId(fd, file)) return CELL_ESRCH; 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 = file->GetSize(); sb->st_blksize = 4096; return CELL_OK; }