feat: Add Retro Game Launcher and Player components with ROM selection and streaming options

This commit is contained in:
2025-12-30 12:02:29 +00:00
parent 4f73478241
commit 2f53941935
+555
View File
@@ -739,6 +739,561 @@
"children": "Markdown → EPUB"
}
]
},
{
"id": "RetroGameLauncher",
"type": "container",
"props": { "sx": { "p": 3 } },
"children": [
{
"type": "typography",
"props": { "variant": "h5", "gutterBottom": true },
"children": "Retro Gaming"
},
{
"type": "grid",
"props": { "container": true, "spacing": 3 },
"children": [
{
"type": "grid",
"props": { "item": true, "xs": 12, "md": 8 },
"children": [
{
"type": "card",
"children": [
{
"type": "cardContent",
"children": [
{
"type": "typography",
"props": { "variant": "h6", "gutterBottom": true },
"children": "Start New Game"
},
{
"type": "form",
"props": { "id": "retro-launch-form" },
"children": [
{
"type": "fileUpload",
"props": {
"name": "rom_file",
"label": "Select ROM",
"accept": ".nes,.sfc,.smc,.gba,.gb,.gbc,.n64,.z64,.bin,.iso,.cue,.chd,.zip,.7z",
"fullWidth": true,
"sx": { "mb": 2 }
}
},
{
"type": "select",
"props": {
"name": "core",
"label": "Emulator Core",
"fullWidth": true,
"sx": { "mb": 2 },
"options": "{{available_cores}}"
}
},
{
"type": "select",
"props": {
"name": "shader",
"label": "Shader Preset",
"fullWidth": true,
"sx": { "mb": 2 },
"defaultValue": "none",
"options": [
{ "value": "none", "label": "None (Sharp Pixels)" },
{ "value": "crt_royale", "label": "CRT Royale" },
{ "value": "crt_lottes", "label": "CRT Lottes" },
{ "value": "scanlines", "label": "Scanlines" },
{ "value": "lcd_grid", "label": "LCD Grid (Handheld)" },
{ "value": "xbrz", "label": "xBRZ Upscaling" }
]
}
},
{
"type": "grid",
"props": { "container": true, "spacing": 2, "sx": { "mb": 2 } },
"children": [
{
"type": "grid",
"props": { "item": true, "xs": 6 },
"children": [
{
"type": "select",
"props": {
"name": "resolution",
"label": "Resolution",
"fullWidth": true,
"defaultValue": "720p",
"options": [
{ "value": "480p", "label": "480p (SD)" },
{ "value": "720p", "label": "720p (HD)" },
{ "value": "1080p", "label": "1080p (Full HD)" },
{ "value": "1440p", "label": "1440p (2K)" },
{ "value": "4k", "label": "4K (UHD)" }
]
}
}
]
},
{
"type": "grid",
"props": { "item": true, "xs": 6 },
"children": [
{
"type": "formControlLabel",
"props": {
"control": {
"type": "checkbox",
"props": { "name": "integer_scaling" }
},
"label": "Integer Scaling"
}
}
]
}
]
},
{
"type": "accordion",
"props": { "sx": { "mb": 2 } },
"children": [
{
"type": "accordionSummary",
"props": { "expandIcon": { "type": "icon", "props": { "name": "ExpandMore" } } },
"children": "Streaming Options"
},
{
"type": "accordionDetails",
"children": [
{
"type": "formControlLabel",
"props": {
"control": {
"type": "switch",
"props": { "name": "stream_enabled" }
},
"label": "Enable Streaming"
}
},
{
"type": "textField",
"props": {
"name": "stream_url",
"label": "RTMP URL",
"placeholder": "rtmp://live.twitch.tv/app/your_stream_key",
"fullWidth": true,
"sx": { "mt": 2 }
}
}
]
}
]
},
{
"type": "accordion",
"children": [
{
"type": "accordionSummary",
"props": { "expandIcon": { "type": "icon", "props": { "name": "ExpandMore" } } },
"children": "Netplay (Multiplayer)"
},
{
"type": "accordionDetails",
"children": [
{
"type": "formControlLabel",
"props": {
"control": {
"type": "switch",
"props": { "name": "netplay_enabled" }
},
"label": "Enable Netplay"
}
},
{
"type": "radioGroup",
"props": {
"name": "netplay_mode",
"sx": { "mt": 1 }
},
"children": [
{
"type": "formControlLabel",
"props": {
"value": "host",
"control": { "type": "radio" },
"label": "Host Game"
}
},
{
"type": "formControlLabel",
"props": {
"value": "join",
"control": { "type": "radio" },
"label": "Join Game"
}
}
]
},
{
"type": "textField",
"props": {
"name": "netplay_host",
"label": "Host Address (for joining)",
"placeholder": "192.168.1.100:55435",
"fullWidth": true,
"sx": { "mt": 2 }
}
}
]
}
]
}
]
}
]
},
{
"type": "cardActions",
"children": [
{
"type": "button",
"props": {
"variant": "contained",
"color": "primary",
"startIcon": { "type": "icon", "props": { "name": "PlayArrow" } }
},
"events": { "onClick": "submitForm('retro-launch-form', retro_helpers.start_session)" },
"children": "Launch Game"
}
]
}
]
}
]
},
{
"type": "grid",
"props": { "item": true, "xs": 12, "md": 4 },
"children": [
{
"type": "card",
"children": [
{
"type": "cardContent",
"children": [
{
"type": "typography",
"props": { "variant": "h6", "gutterBottom": true },
"children": "Supported Systems"
},
{
"type": "list",
"props": { "dense": true },
"children": [
{
"type": "listItem",
"children": [
{ "type": "listItemIcon", "children": [{ "type": "icon", "props": { "name": "SportsEsports" } }] },
{ "type": "listItemText", "props": { "primary": "Nintendo", "secondary": "NES, SNES, N64, GB/GBC/GBA, DS" } }
]
},
{
"type": "listItem",
"children": [
{ "type": "listItemIcon", "children": [{ "type": "icon", "props": { "name": "SportsEsports" } }] },
{ "type": "listItemText", "props": { "primary": "Sega", "secondary": "Master System, Genesis, Saturn, Dreamcast" } }
]
},
{
"type": "listItem",
"children": [
{ "type": "listItemIcon", "children": [{ "type": "icon", "props": { "name": "SportsEsports" } }] },
{ "type": "listItemText", "props": { "primary": "Sony", "secondary": "PlayStation, PSP" } }
]
},
{
"type": "listItem",
"children": [
{ "type": "listItemIcon", "children": [{ "type": "icon", "props": { "name": "SportsEsports" } }] },
{ "type": "listItemText", "props": { "primary": "Arcade", "secondary": "MAME, Neo Geo, FinalBurn" } }
]
},
{
"type": "listItem",
"children": [
{ "type": "listItemIcon", "children": [{ "type": "icon", "props": { "name": "SportsEsports" } }] },
{ "type": "listItemText", "props": { "primary": "Other", "secondary": "Atari, PC Engine, DOS, ScummVM" } }
]
}
]
}
]
}
]
}
]
}
]
}
]
},
{
"id": "RetroGamePlayer",
"type": "container",
"props": { "sx": { "p": 2, "bgcolor": "#000", "borderRadius": 1 } },
"children": [
{
"type": "box",
"props": {
"sx": {
"position": "relative",
"width": "100%",
"paddingTop": "56.25%",
"bgcolor": "#111"
}
},
"children": [
{
"type": "canvas",
"props": {
"id": "retro-game-canvas",
"sx": {
"position": "absolute",
"top": 0,
"left": 0,
"width": "100%",
"height": "100%",
"imageRendering": "pixelated"
}
}
},
{
"type": "box",
"props": {
"id": "game-overlay",
"sx": {
"position": "absolute",
"bottom": 0,
"left": 0,
"right": 0,
"p": 1,
"background": "linear-gradient(transparent, rgba(0,0,0,0.8))",
"display": "flex",
"justifyContent": "space-between",
"alignItems": "center",
"opacity": 0,
"transition": "opacity 0.3s",
"&:hover": { "opacity": 1 }
}
},
"children": [
{
"type": "box",
"props": { "sx": { "display": "flex", "gap": 1 } },
"children": [
{
"type": "iconButton",
"props": { "color": "inherit", "size": "small" },
"events": { "onClick": "retro_helpers.set_paused(session_id, !is_paused)" },
"children": [{ "type": "icon", "props": { "name": "{{is_paused ? 'PlayArrow' : 'Pause'}}" } }]
},
{
"type": "iconButton",
"props": { "color": "inherit", "size": "small" },
"events": { "onClick": "retro_helpers.save_state(session_id)" },
"children": [{ "type": "icon", "props": { "name": "Save" } }]
},
{
"type": "iconButton",
"props": { "color": "inherit", "size": "small" },
"events": { "onClick": "openDialog('LoadState')" },
"children": [{ "type": "icon", "props": { "name": "FolderOpen" } }]
},
{
"type": "iconButton",
"props": { "color": "inherit", "size": "small" },
"events": { "onClick": "retro_helpers.take_screenshot(session_id)" },
"children": [{ "type": "icon", "props": { "name": "CameraAlt" } }]
},
{
"type": "iconButton",
"props": { "color": "inherit", "size": "small" },
"events": { "onClick": "retro_helpers.set_fast_forward(session_id, !fast_forward)" },
"children": [{ "type": "icon", "props": { "name": "FastForward", "color": "{{fast_forward ? 'primary' : 'inherit'}}" } }]
}
]
},
{
"type": "typography",
"props": { "variant": "caption", "color": "grey.400" },
"children": "{{fps}} FPS | {{retro_helpers.format_playtime(play_time)}}"
},
{
"type": "box",
"props": { "sx": { "display": "flex", "gap": 1 } },
"children": [
{
"type": "iconButton",
"props": { "color": "inherit", "size": "small" },
"events": { "onClick": "openDialog('ShaderPicker')" },
"children": [{ "type": "icon", "props": { "name": "Tune" } }]
},
{
"type": "iconButton",
"props": { "color": "inherit", "size": "small" },
"events": { "onClick": "toggleFullscreen('retro-game-canvas')" },
"children": [{ "type": "icon", "props": { "name": "Fullscreen" } }]
}
]
}
]
}
]
},
{
"type": "box",
"props": { "sx": { "mt": 1, "display": "flex", "justifyContent": "space-between", "alignItems": "center" } },
"children": [
{
"type": "typography",
"props": { "variant": "subtitle1", "color": "grey.300" },
"children": "{{rom_name}}"
},
{
"type": "chip",
"props": {
"label": "{{core_name}}",
"size": "small",
"color": "primary",
"variant": "outlined"
}
}
]
}
]
},
{
"id": "SaveStateManager",
"type": "dialog",
"props": { "maxWidth": "md", "fullWidth": true },
"children": [
{
"type": "dialogTitle",
"children": "Save States"
},
{
"type": "dialogContent",
"children": [
{
"type": "grid",
"props": { "container": true, "spacing": 2 },
"children": [
{
"type": "iterator",
"dataSource": "save_states",
"itemTemplate": {
"type": "grid",
"props": { "item": true, "xs": 6, "sm": 4, "md": 3 },
"children": [
{
"type": "card",
"props": {
"sx": {
"cursor": "pointer",
"&:hover": { "boxShadow": 4 }
}
},
"events": { "onClick": "retro_helpers.load_state(session_id, {{item.slot}})" },
"children": [
{
"type": "cardMedia",
"props": {
"component": "img",
"height": "120",
"image": "{{item.screenshot_path}}",
"alt": "Slot {{item.slot}}"
}
},
{
"type": "cardContent",
"props": { "sx": { "py": 1 } },
"children": [
{
"type": "typography",
"props": { "variant": "subtitle2" },
"children": "Slot {{item.slot}}"
},
{
"type": "typography",
"props": { "variant": "caption", "color": "text.secondary" },
"children": "{{formatDate(item.created_at)}}"
}
]
}
]
}
]
}
}
]
}
]
},
{
"type": "dialogActions",
"children": [
{
"type": "button",
"events": { "onClick": "closeDialog()" },
"children": "Close"
}
]
}
]
},
{
"id": "ActiveSessionsList",
"type": "container",
"children": [
{
"type": "typography",
"props": { "variant": "h6", "gutterBottom": true },
"children": "Active Sessions"
},
{
"type": "dataTable",
"props": {
"columns": [
{ "field": "rom_name", "headerName": "Game", "flex": 1 },
{ "field": "core_name", "headerName": "Core", "width": 120 },
{ "field": "fps", "headerName": "FPS", "width": 80 },
{ "field": "play_time", "headerName": "Time", "width": 100, "valueFormatter": "retro_helpers.format_playtime" },
{ "field": "status", "headerName": "Status", "width": 100 },
{ "field": "actions", "headerName": "", "width": 120 }
],
"dataSource": "active_sessions",
"rowActions": [
{
"icon": "Visibility",
"tooltip": "View",
"onClick": "navigateTo('/media/retro/' + row.session_id)"
},
{
"icon": "Stop",
"tooltip": "Stop",
"onClick": "retro_helpers.stop_session(row.session_id)"
}
]
}
}
]
}
]
}