Skip to content

Commit 68efbde

Browse files
committed
Multiple opinioned FNA-NET patches
- 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 - Enables advanced CJK text input API with ImeSharp - Add GameWindowEXT.cs - Add MouseCursorEXT.cs - Add InputEventEXT.cs, the traditional event-based input system
1 parent d3a0b7d commit 68efbde

23 files changed

+2756
-133
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

.github/workflows/ci.yml

Lines changed: 0 additions & 37 deletions
This file was deleted.

FNA.NET.csproj

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

FNA.NET.sln

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
2+
Microsoft Visual Studio Solution File, Format Version 12.00
3+
# Visual Studio Version 17
4+
VisualStudioVersion = 17.0.31903.59
5+
MinimumVisualStudioVersion = 10.0.40219.1
6+
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "FNA.NET", "FNA.NET.csproj", "{41F03AD7-A010-4B10-B396-FBCE4D3BC894}"
7+
EndProject
8+
Global
9+
GlobalSection(SolutionConfigurationPlatforms) = preSolution
10+
Debug|Any CPU = Debug|Any CPU
11+
Debug|x64 = Debug|x64
12+
Debug|x86 = Debug|x86
13+
Release|Any CPU = Release|Any CPU
14+
Release|x64 = Release|x64
15+
Release|x86 = Release|x86
16+
EndGlobalSection
17+
GlobalSection(ProjectConfigurationPlatforms) = postSolution
18+
{41F03AD7-A010-4B10-B396-FBCE4D3BC894}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
19+
{41F03AD7-A010-4B10-B396-FBCE4D3BC894}.Debug|Any CPU.Build.0 = Debug|Any CPU
20+
{41F03AD7-A010-4B10-B396-FBCE4D3BC894}.Debug|x64.ActiveCfg = Debug|Any CPU
21+
{41F03AD7-A010-4B10-B396-FBCE4D3BC894}.Debug|x64.Build.0 = Debug|Any CPU
22+
{41F03AD7-A010-4B10-B396-FBCE4D3BC894}.Debug|x86.ActiveCfg = Debug|Any CPU
23+
{41F03AD7-A010-4B10-B396-FBCE4D3BC894}.Debug|x86.Build.0 = Debug|Any CPU
24+
{41F03AD7-A010-4B10-B396-FBCE4D3BC894}.Release|Any CPU.ActiveCfg = Release|Any CPU
25+
{41F03AD7-A010-4B10-B396-FBCE4D3BC894}.Release|Any CPU.Build.0 = Release|Any CPU
26+
{41F03AD7-A010-4B10-B396-FBCE4D3BC894}.Release|x64.ActiveCfg = Release|Any CPU
27+
{41F03AD7-A010-4B10-B396-FBCE4D3BC894}.Release|x64.Build.0 = Release|Any CPU
28+
{41F03AD7-A010-4B10-B396-FBCE4D3BC894}.Release|x86.ActiveCfg = Release|Any CPU
29+
{41F03AD7-A010-4B10-B396-FBCE4D3BC894}.Release|x86.Build.0 = Release|Any CPU
30+
EndGlobalSection
31+
GlobalSection(SolutionProperties) = preSolution
32+
HideSolutionNode = FALSE
33+
EndGlobalSection
34+
EndGlobal

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: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
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 opinioned fork of FNA. Its goal is to bring FNA to nuget package manager. It also contains some custom modification and extensions.
5+
6+
## Supported Platforms
7+
8+
### Android
9+
10+
| OS | Architectures | Renderer |
11+
| ----------------------------- | --------------------- | -------------------- |
12+
| Android | Arm64 | OpenGL |
13+
| Android | Arm64 | Vulkan(some devices) |
14+
15+
Notes:
16+
17+
* Android: It should run with OpenGL on most modern devices. It runs with Vulkan on few devices since it has driver issues.
18+
* Android: Emulator is not supported as SDL3 GPU has no support for it.
19+
20+
### Apple
21+
22+
| OS | Architectures | Renderer |
23+
| ----------------------------- | --------------------- | ---------------------------- |
24+
| iOS | Arm64 | OpenGL, Metal |
25+
| macOS | Arm64, x64 | OpenGL, Metal |
26+
| tvOS | Arm64 | OpenGL, Metal |
27+
28+
Notes:
29+
30+
* iOS/tvOS: Simulator is not supported as SDL3 GPU has no support for it.
31+
32+
### Windows
33+
34+
| OS | Architectures | Renderer |
35+
| ----------------------------- | --------------------- | ---------------------------- |
36+
| Windows | x64 | OpenGL, D3D11, D3D12, Vulkan |
37+
38+
### Linux
39+
40+
| OS | Architectures | Renderer |
41+
| ----------------------------- | --------------------- | ---------------------------- |
42+
| Ubuntu | x64, arm64 | OpenGL, Vulkan |
43+
44+
Notes:
45+
46+
* Linux: Other Linux OS is not tested but it should work.
47+
48+
## FNA Documentation
49+
50+
https://fna-xna.github.io/docs/

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)