Skip to content

Commit 8b4cb2e

Browse files
committed
Multiple FNA-NET changes
- Enable CI for FNA-NET project - Add lz4 compress xnb content support - Android: Fix loading ogg song asset by copy assets to app Internal Storage - Add DynamicMediaPlayer to play musics - Resolve build warnings - iOS: fix build error on `MediaPlayer` naming colision
1 parent d3a0b7d commit 8b4cb2e

File tree

14 files changed

+1683
-93
lines changed

14 files changed

+1683
-93
lines changed

.github/workflows/FNA-NET.yml

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
name: FNA.NET CI
2+
3+
on: [push, pull_request]
4+
5+
jobs:
6+
windows:
7+
name: Windows
8+
runs-on: windows-latest
9+
steps:
10+
- uses: actions/checkout@v4
11+
with:
12+
submodules: true
13+
14+
- name: Install workloads
15+
run: |
16+
dotnet workload install android ios tvos --skip-manifest-update
17+
18+
- name: dotnet build and pack FNA.NET
19+
run: |
20+
dotnet build -c Debug FNA.NET.csproj
21+
dotnet pack FNA.NET.csproj
22+
23+
- uses: actions/upload-artifact@v4
24+
with:
25+
name: ${{ github.event.repository.name }} Artifacts
26+
path: |
27+
bin/Release/*.nupkg

FNA.NET.csproj

Lines changed: 427 additions & 0 deletions
Large diffs are not rendered by default.

FNA.NET.targets

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
<Project>
2+
<ItemGroup>
3+
<Files Include="$(MSBuildThisFileDirectory)/../contentFiles/*.*" />
4+
</ItemGroup>
5+
<Target Name="CopyFiles" AfterTargets="Build" Condition="'$(TargetFramework)' != 'net8.0-android' And '$(TargetFramework)' != 'net8.0-ios' And '$(TargetFramework)' != 'net8.0-tvos'">
6+
<Copy SourceFiles="@(Files)" DestinationFolder="$(TargetDir)" />
7+
</Target>
8+
</Project>

README.md

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
# FNA.NET
2+
[![Nuget](https://img.shields.io/nuget/vpre/FNA.NET)](https://www.nuget.org/packages/FNA.NET/)
3+
4+
FNA.NET is a variant of FNA. Its goal is to develop games with FNA/XNA on the modern .NET platform.
5+
6+
## Supported Platforms
7+
8+
Android is **supported** with Vulkan!
9+
10+
- Desktop PCs
11+
- Windows Direct3D
12+
- Windows Vulkan
13+
- Linux Vulkan
14+
- macOS Metal
15+
- Mobile/Tablet Devices
16+
- iOS/tvOS Metal
17+
- Android Vulkan
18+
19+
## Documentation
20+
21+
Documentation for FNA can be found on the FNA wiki:
22+
23+
https://github.com/FNA-XNA/FNA/wiki

src/Content/ContentManager.cs

Lines changed: 19 additions & 84 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,9 @@ namespace Microsoft.Xna.Framework.Content
2323
{
2424
public partial class ContentManager : IDisposable
2525
{
26+
const byte ContentCompressedLzx = 0x80;
27+
const byte ContentCompressedLz4 = 0x40;
28+
2629
#region Public ServiceProvider Property
2730

2831
public IServiceProvider ServiceProvider
@@ -463,99 +466,31 @@ private ContentReader GetContentReaderFromXnb(string originalAssetName, ref Stre
463466
{
464467
byte version = xnbReader.ReadByte();
465468
byte flags = xnbReader.ReadByte();
466-
bool compressed = (flags & 0x80) != 0;
469+
470+
bool compressedLzx = (flags & ContentCompressedLzx) != 0;
471+
bool compressedLz4 = (flags & ContentCompressedLz4) != 0;
467472
if (version != 5 && version != 4)
468473
{
469474
throw new ContentLoadException("Invalid XNB version");
470475
}
471476
// The next int32 is the length of the XNB file
472477
int xnbLength = xnbReader.ReadInt32();
473478
ContentReader reader;
474-
if (compressed)
479+
if (compressedLzx || compressedLz4)
475480
{
476-
/* Decompress the XNB
477-
* Thanks to ShinAli (https://bitbucket.org/alisci01/xnbdecompressor)
478-
*/
479-
int compressedSize = xnbLength - 14;
481+
// Decompress the xnb
480482
int decompressedSize = xnbReader.ReadInt32();
481483

482-
// This will replace the XNB stream at the end
483-
MemoryStream decompressedStream = new MemoryStream(
484-
new byte[decompressedSize],
485-
0,
486-
decompressedSize,
487-
true,
488-
true // This MUST be true! Readers may need GetBuffer()!
489-
);
490-
491-
/* Read in the whole XNB file at once, into a temp buffer.
492-
* For slow disks, the extra malloc is more than worth the
493-
* performance improvement from not constantly fread()ing!
494-
*/
495-
MemoryStream compressedStream = new MemoryStream(
496-
new byte[compressedSize],
497-
0,
498-
compressedSize,
499-
true,
500-
true
501-
);
502-
stream.Read(compressedStream.GetBuffer(), 0, compressedSize);
503-
504-
// Default window size for XNB encoded files is 64Kb (need 16 bits to represent it)
505-
LzxDecoder dec = new LzxDecoder(16);
506-
int decodedBytes = 0;
507-
long pos = 0;
508-
509-
while (pos < compressedSize)
484+
Stream decompressedStream = null;
485+
if (compressedLzx)
510486
{
511-
/* The compressed stream is separated into blocks that will
512-
* decompress into 32kB or some other size if specified.
513-
* Normal, 32kB output blocks will have a short indicating
514-
* the size of the block before the block starts. Blocks
515-
* that have a defined output will be preceded by a byte of
516-
* value 0xFF (255), then a short indicating the output size
517-
* and another for the block size. All shorts for these
518-
* cases are encoded in big endian order.
519-
*/
520-
int hi = compressedStream.ReadByte();
521-
int lo = compressedStream.ReadByte();
522-
int block_size = (hi << 8) | lo;
523-
int frame_size = 0x8000; // Frame size is 32kB by default
524-
// Does this block define a frame size?
525-
if (hi == 0xFF)
526-
{
527-
hi = lo;
528-
lo = (byte) compressedStream.ReadByte();
529-
frame_size = (hi << 8) | lo;
530-
hi = (byte) compressedStream.ReadByte();
531-
lo = (byte) compressedStream.ReadByte();
532-
block_size = (hi << 8) | lo;
533-
pos += 5;
534-
}
535-
else
536-
{
537-
pos += 2;
538-
}
539-
// Either says there is nothing to decode
540-
if (block_size == 0 || frame_size == 0)
541-
{
542-
break;
543-
}
544-
dec.Decompress(compressedStream, block_size, decompressedStream, frame_size);
545-
pos += block_size;
546-
decodedBytes += frame_size;
547-
/* Reset the position of the input just in case the bit
548-
* buffer read in some unused bytes.
549-
*/
550-
compressedStream.Seek(pos, SeekOrigin.Begin);
487+
int compressedSize = xnbLength - 14;
488+
decompressedStream = new LzxDecoderStream(stream, decompressedSize, compressedSize);
551489
}
552-
if (decompressedStream.Position != decompressedSize)
490+
else if (compressedLz4)
553491
{
554-
throw new ContentLoadException(
555-
"Decompression of " + originalAssetName + " failed. "
556-
);
492+
decompressedStream = new Lz4DecoderStream(stream);
557493
}
558-
decompressedStream.Seek(0, SeekOrigin.Begin);
559494
reader = new ContentReader(
560495
this,
561496
decompressedStream,
@@ -599,13 +534,13 @@ private Stream CheckRawExtensions(string assetName, string[] extensions)
599534
}
600535
}
601536

602-
// If we got here, we need to try the slower path :(
537+
// If we got here, we need to try the slower path :(. We load android raw assets here :)
603538
fileName = MonoGame.Utilities.FileHelpers.NormalizeFilePathSeparators(
604-
assetName
539+
Path.Combine(RootDirectory, assetName)
605540
);
606541
try
607542
{
608-
return OpenStream(fileName);
543+
return TitleContainer.OpenStream(fileName);
609544
}
610545
catch
611546
{
@@ -615,7 +550,7 @@ private Stream CheckRawExtensions(string assetName, string[] extensions)
615550
string fileNamePlusExt = fileName + ext;
616551
try
617552
{
618-
return OpenStream(fileNamePlusExt);
553+
return TitleContainer.OpenStream(fileNamePlusExt);
619554
}
620555
catch
621556
{
@@ -708,4 +643,4 @@ private static void RemoveContentManager(ContentManager contentManager)
708643

709644
#endregion
710645
}
711-
}
646+
}

0 commit comments

Comments
 (0)