Example #1
0
        private T ReadObjectFromSharedMemory <T>(ulong offset, ulong padding) where T : unmanaged
        {
            T    result;
            uint index;
            uint possiblyNewIndex;

            do
            {
                index = _timeSharedMemoryStorage.GetRef <uint>(offset);

                ulong objectOffset = offset + 4 + padding + (ulong)((index & 1) * Unsafe.SizeOf <T>());

                result = _timeSharedMemoryStorage.GetRef <T>(objectOffset);

                Thread.MemoryBarrier();

                possiblyNewIndex = _device.Memory.Read <uint>(offset);
            } while (index != possiblyNewIndex);

            return(result);
        }
Example #2
0
        public void EnsureInitialized(ContentManager contentManager)
        {
            if (_fontData == null)
            {
                _storage.ZeroFill();

                uint fontOffset = 0;

                FontInfo CreateFont(string name)
                {
                    if (contentManager.TryGetFontTitle(name, out ulong fontTitle) && contentManager.TryGetFontFilename(name, out string fontFilename))
                    {
                        string contentPath = contentManager.GetInstalledContentPath(fontTitle, StorageId.BuiltInSystem, NcaContentType.Data);
                        string fontPath    = _device.FileSystem.SwitchPathToSystemPath(contentPath);

                        if (!string.IsNullOrWhiteSpace(fontPath))
                        {
                            byte[] data;

                            using (IStorage ncaFileStream = new LocalStorage(fontPath, FileAccess.Read, FileMode.Open))
                            {
                                Nca         nca   = new Nca(_device.System.KeySet, ncaFileStream);
                                IFileSystem romfs = nca.OpenFileSystem(NcaSectionType.Data, _device.System.FsIntegrityCheckLevel);

                                using var fontFile = new UniqueRef <IFile>();

                                romfs.OpenFile(ref fontFile.Ref(), ("/" + fontFilename).ToU8Span(), OpenMode.Read).ThrowIfFailure();

                                data = DecryptFont(fontFile.Get.AsStream());
                            }

                            FontInfo info = new FontInfo((int)fontOffset, data.Length);

                            WriteMagicAndSize(fontOffset, data.Length);

                            fontOffset += 8;

                            uint start = fontOffset;

                            for (; fontOffset - start < data.Length; fontOffset++)
                            {
                                _storage.GetRef <byte>(fontOffset) = data[fontOffset - start];
                            }

                            return(info);
                        }
                        else
                        {
                            if (!contentManager.TryGetSystemTitlesName(fontTitle, out string titleName))
                            {
                                titleName = "Unknown";
                            }

                            throw new InvalidSystemResourceException($"{titleName} ({fontTitle:x8}) system title not found! This font will not work, provide the system archive to fix this error. (See https://github.com/Ryujinx/Ryujinx#requirements for more information)");
                        }
                    }
                    else
                    {
                        throw new ArgumentException($"Unknown font \"{name}\"!");
                    }
                }

                _fontData = new Dictionary <SharedFontType, FontInfo>
                {
                    { SharedFontType.JapanUsEurope, CreateFont("FontStandard") },
                    { SharedFontType.SimplifiedChinese, CreateFont("FontChineseSimplified") },
                    { SharedFontType.SimplifiedChineseEx, CreateFont("FontExtendedChineseSimplified") },
                    { SharedFontType.TraditionalChinese, CreateFont("FontChineseTraditional") },
                    { SharedFontType.Korean, CreateFont("FontKorean") },
                    { SharedFontType.NintendoEx, CreateFont("FontNintendoExtended") }
                };

                if (fontOffset > Horizon.FontSize)
                {
                    throw new InvalidSystemResourceException("The sum of all fonts size exceed the shared memory size. " +
                                                             $"Please make sure that the fonts don't exceed {Horizon.FontSize} bytes in total. (actual size: {fontOffset} bytes).");
                }
            }
        }