mirror of
https://github.com/Ryujinx/Ryujinx.git
synced 2024-12-29 05:51:20 -08:00
22bacc6188
* Implement some IPC related kernel SVCs properly * Fix BLZ decompression when the segment also has a uncompressed chunck * Set default cpu core on process start from ProgramLoader, remove debug message * Load process capabilities properly on KIPs * Fix a copy/paste error in UnmapPhysicalMemory64 * Implement smarter switching between old and new IPC system to support the old HLE services implementation without the manual switch * Implement RegisterService on sm and AcceptSession (partial) * Misc fixes and improvements on new IPC methods * Move IPC related SVCs into a separate file, and logging on RegisterService (sm) * Some small fixes related to receive list buffers and error cases * Load NSOs using the correct pool partition * Fix corner case on GetMaskFromMinMax where range is 64, doesn't happen in pratice however * Fix send static buffer copy * Session release, implement closing requests on client disconnect * Implement ConnectToPort SVC * KLightSession init
107 lines
2.9 KiB
C#
107 lines
2.9 KiB
C#
using System;
|
|
|
|
namespace Ryujinx.HLE.Loaders.Compression
|
|
{
|
|
static class BackwardsLz
|
|
{
|
|
private class BackwardsReader
|
|
{
|
|
private byte[] _data;
|
|
|
|
private int _position;
|
|
|
|
public int Position => _position;
|
|
|
|
public BackwardsReader(byte[] data, int end)
|
|
{
|
|
_data = data;
|
|
_position = end;
|
|
}
|
|
|
|
public void SeekCurrent(int offset)
|
|
{
|
|
_position += offset;
|
|
}
|
|
|
|
public byte ReadByte()
|
|
{
|
|
return _data[--_position];
|
|
}
|
|
|
|
public short ReadInt16()
|
|
{
|
|
return (short)((ReadByte() << 8) | (ReadByte() << 0));
|
|
}
|
|
|
|
public int ReadInt32()
|
|
{
|
|
return ((ReadByte() << 24) |
|
|
(ReadByte() << 16) |
|
|
(ReadByte() << 8) |
|
|
(ReadByte() << 0));
|
|
}
|
|
}
|
|
|
|
public static void DecompressInPlace(byte[] buffer, int headerEnd)
|
|
{
|
|
BackwardsReader reader = new BackwardsReader(buffer, headerEnd);
|
|
|
|
int additionalDecLength = reader.ReadInt32();
|
|
int startOffset = reader.ReadInt32();
|
|
int compressedLength = reader.ReadInt32();
|
|
|
|
reader.SeekCurrent(12 - startOffset);
|
|
|
|
int decBase = headerEnd - compressedLength;
|
|
|
|
int decPos = compressedLength + additionalDecLength;
|
|
|
|
byte mask = 0;
|
|
byte header = 0;
|
|
|
|
while (decPos > 0)
|
|
{
|
|
if ((mask >>= 1) == 0)
|
|
{
|
|
header = reader.ReadByte();
|
|
mask = 0x80;
|
|
}
|
|
|
|
if ((header & mask) == 0)
|
|
{
|
|
buffer[decBase + --decPos] = reader.ReadByte();
|
|
}
|
|
else
|
|
{
|
|
ushort pair = (ushort)reader.ReadInt16();
|
|
|
|
int length = (pair >> 12) + 3;
|
|
int position = (pair & 0xfff) + 3;
|
|
|
|
if (length > decPos)
|
|
{
|
|
length = decPos;
|
|
}
|
|
|
|
decPos -= length;
|
|
|
|
int dstPos = decBase + decPos;
|
|
|
|
if (length <= position)
|
|
{
|
|
int srcPos = dstPos + position;
|
|
|
|
Buffer.BlockCopy(buffer, srcPos, buffer, dstPos, length);
|
|
}
|
|
else
|
|
{
|
|
for (int offset = 0; offset < length; offset++)
|
|
{
|
|
buffer[dstPos + offset] = buffer[dstPos + position + offset];
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
} |