private static readonly ReferenceTable Files = new ReferenceTable(); private static RESULT FSUserSeek(IntPtr handle, uint pos, IntPtr userdata) { WrappingStream? stream = Files.TryGet(handle); if (stream == null) return RESULT.ERR_FILE_BAD; if (!stream.Underlying.CanSeek) { stream.Underlying = new MemoryStream(Content.LoadBytes(stream.ContentPath)); } stream.Position = pos; return RESULT.OK; } private static unsafe RESULT FSUserRead(IntPtr handle, IntPtr buffer, uint sizebytes, ref uint bytesread, IntPtr userdata) { WrappingStream? stream = Files.TryGet(handle); if (stream == null) return RESULT.ERR_FILE_BAD; Span readSpan = new ((byte*)buffer, (int)sizebytes); bytesread = (uint)stream.Read(readSpan); return bytesread < sizebytes ? RESULT.ERR_FILE_EOF : RESULT.OK; } private static RESULT FSUserClose(IntPtr handle, IntPtr userdata) { WrappingStream? stream = Files.TryGet(handle); if (stream == null) return RESULT.ERR_FILE_BAD; stream.Close(); Files.Free(handle); return RESULT.OK; } private static RESULT FSUserOpen(IntPtr name, ref uint filesize, ref IntPtr handle, IntPtr userdata) { ContentLump? lump = Content.Load(name.GetString()); if (lump == null) return RESULT.ERR_FILE_NOTFOUND; WrappingStream stream = new WrappingStream(Content.LoadStream(lump)); stream.ContentPath = name.GetString(); handle = Files.Create(stream); return RESULT.OK; }