Add Game Icon

This commit is contained in:
Stossy11 2024-12-09 19:18:37 +11:00
parent e81ee8f8bf
commit 94dc643f26
5 changed files with 88 additions and 32 deletions

View File

@ -21,7 +21,10 @@ struct GameInfo {
long TitleId;
char Developer[256];
int Version;
unsigned char* ImageData;
unsigned int ImageSize;
};
extern struct GameInfo get_game_info(int, char*);
// Declare the main_ryujinx_sdl function, matching the signature
int main_ryujinx_sdl(int argc, char **argv);

View File

@ -20,5 +20,26 @@ public struct Game: Identifiable, Equatable {
var titleId: String
var developer: String
var version: String
var icon: Image?
var icon: UIImage?
func createImage(from gameInfo: GameInfo) -> UIImage? {
// Access the struct
let gameInfoValue = gameInfo
// Get the image data
let imageSize = Int(gameInfoValue.ImageSize)
guard imageSize > 0, imageSize <= 1024 * 1024 else {
print("Invalid image size.")
return nil
}
// Convert the ImageData byte array to Swift's Data
let imageData = Data(bytes: gameInfoValue.ImageData, count: imageSize)
// Create a UIImage (or NSImage on macOS)
print(imageData)
return UIImage(data: imageData)
}
}

View File

@ -221,6 +221,8 @@ struct GameLibraryView: View {
game.version = String(gameInfo.Version)
game.icon = game.createImage(from: gameInfo)
games.append(game)
} catch {
@ -274,7 +276,7 @@ struct RecentGameCard: View {
}) {
VStack(alignment: .leading, spacing: 8) {
if let icon = game.icon {
icon
Image(uiImage: icon)
.resizable()
.aspectRatio(contentMode: .fill)
.frame(width: 140, height: 140)
@ -321,7 +323,7 @@ struct GameListRow: View {
HStack(spacing: 16) {
// Game Icon
if let icon = game.icon {
icon
Image(uiImage: icon)
.resizable()
.aspectRatio(contentMode: .fill)
.frame(width: 45, height: 45)

View File

@ -273,7 +273,7 @@ namespace Ryujinx.Headless.SDL2
var gameInfo = GetGameInfo(stream, extension);
return new GameInfoNative(0, gameInfo.TitleName, 0, gameInfo.Developer, 0);
return new GameInfoNative(0, gameInfo.TitleName, 0, gameInfo.Developer, 0, gameInfo.Icon);
}
public static GameInfo? GetGameInfo(Stream gameStream, string extension)
@ -1386,15 +1386,17 @@ namespace Ryujinx.Headless.SDL2
public byte[]? Icon;
}
public unsafe struct GameInfoNative
{
public unsafe struct GameInfoNative
{
public ulong FileSize;
public fixed byte TitleName[512];
public ulong TitleId;
public fixed byte Developer[256];
public uint Version;
public byte* ImageData; // Changed to pointer
public uint ImageSize; // Actual size of image data
public GameInfoNative(ulong fileSize, string titleName, ulong titleId, string developer, uint version)
public GameInfoNative(ulong fileSize, string titleName, ulong titleId, string developer, uint version, byte[] imageData)
{
FileSize = fileSize;
TitleId = titleId;
@ -1406,13 +1408,41 @@ namespace Ryujinx.Headless.SDL2
CopyStringToFixedArray(titleName, titleNamePtr, 512);
CopyStringToFixedArray(developer, developerPtr, 256);
}
if (imageData == null || imageData.Length > 1024 * 1024)
{
throw new ArgumentException("Image data must not exceed 1 MB.");
}
private void CopyStringToFixedArray(string source, byte* destination, int length)
ImageSize = (uint)imageData.Length;
// Allocate unmanaged memory for the image data
ImageData = (byte*)Marshal.AllocHGlobal(imageData.Length);
// Copy the image data to the allocated memory
Marshal.Copy(imageData, 0, (IntPtr)ImageData, imageData.Length);
}
// Don't forget to free the allocated memory
public void Dispose()
{
if (ImageData != null)
{
Marshal.FreeHGlobal((IntPtr)ImageData);
ImageData = null;
}
}
private static void CopyStringToFixedArray(string source, byte* destination, int length)
{
var span = new Span<byte>(destination, length);
Encoding.UTF8.GetBytes(source, span);
}
private static void CopyArrayToFixedArray(byte[] source, byte* destination, int maxLength)
{
var span = new Span<byte>(destination, maxLength);
source.AsSpan().CopyTo(span);
}
}
}
}