Skip to content

Commit f644185

Browse files
committed
refactor: Make launch embed a toggle to replace standalone
fix: Make watch() work for exts fix: Make sure Ruffle embed uses NGA sizing when available
1 parent c7cc2ef commit f644185

File tree

13 files changed

+72
-44
lines changed

13 files changed

+72
-44
lines changed

extensions/core-nga/gulpfile.js

Lines changed: 9 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@ async function build(done) {
3434
.finally(done);
3535
}
3636

37-
async function watch() {
37+
async function watch(done) {
3838
const ctx = await esbuild.context({
3939
bundle: true,
4040
entryPoints: ['./src/extension.ts'],
@@ -43,17 +43,16 @@ async function watch() {
4343
external: ['flashpoint-launcher', '*.css'],
4444
});
4545

46-
const ctx2 = await esbuild.context({
47-
bundle: true,
48-
entryPoints: ['./src/components.ts'],
49-
outfile: './static/components.js',
50-
format: 'esm',
51-
target: ['es2020'],
52-
platform: 'browser',
53-
external: ['flashpoint-launcher', '*.css'],
46+
const config = await loadConfig('./rslib.config.ts');
47+
const renderer = rslibBuild({
48+
...config.content,
49+
mode: 'development',
50+
watch: true
5451
});
5552

56-
return Promise.all([ctx.watch(), ctx2.watch()]);
53+
return Promise.all([ctx.watch(), renderer])
54+
.catch(console.error)
55+
.finally(done);
5756
}
5857

5958
function clean(cb) {

extensions/core-ruffle/gulpfile.js

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -34,15 +34,25 @@ async function build(done) {
3434
.finally(done);
3535
}
3636

37-
async function watch() {
37+
async function watch(done) {
3838
const ctx = await esbuild.context({
3939
bundle: true,
4040
entryPoints: ['./src/extension.ts'],
4141
outfile: './dist/extension.js',
4242
platform: 'node',
4343
external: ['flashpoint-launcher'],
4444
});
45-
return ctx.watch();
45+
46+
const config = await loadConfig('./rslib.config.ts');
47+
const renderer = rslibBuild({
48+
...config.content,
49+
mode: 'development',
50+
watch: true
51+
});
52+
53+
return Promise.all([ctx.watch(), renderer])
54+
.catch(console.error)
55+
.finally(done);
4656
}
4757

4858
function clean(cb) {

extensions/core-ruffle/package.json

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,12 @@
3030
"default": false,
3131
"description": "Enables Ruffle Standalone for all games regardless of whether they have been checked as supported. Results my vary."
3232
},
33+
"com.ruffle.use-launcher-embed": {
34+
"title": "Use Launcher Embed",
35+
"type": "boolean",
36+
"default": false,
37+
"description": "Uses Ruffle embedded in the Launcher instead of the Standalone application. Saves will not carry over."
38+
},
3339
"com.ruffle.graphics-mode": {
3440
"title": "Graphics Mode",
3541
"type": "string",

extensions/core-ruffle/src/components/LauncherEmbedPage.tsx

Lines changed: 20 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,19 @@ export default function LauncherEmbedPage(props: GameLaunchInfo) {
66
const navigate = window.ext.hooks.useNavigate();
77
const ruffleJsUrl = React.useMemo(() => `${window.ext.utils.getFileServerURL()}/ruffle/webhosted/latest/ruffle.js`, []);
88

9+
let width: string | undefined, height: string | undefined;
10+
if (props.game.extData?.nga) {
11+
// It's an NGA game, so it must have width and height in info
12+
width = props.game.extData?.nga['width'];
13+
if (width) {
14+
width += 'px';
15+
}
16+
height = props.game.extData?.nga['height'];
17+
if (height) {
18+
height += 'px';
19+
}
20+
}
21+
922
React.useEffect(() => {
1023
// useEffect calls on a ref change as well, even with no deps
1124
if (!(window as any).RufflePatched) {
@@ -15,13 +28,14 @@ export default function LauncherEmbedPage(props: GameLaunchInfo) {
1528
elem.onload = () => {
1629
console.log('js script loaded');
1730
if (containerRef.current && (window as any).RufflePlayer) {
31+
const lc = props.activeData?.launchCommand;
1832
try {
1933
const ruffle = (window as any).RufflePlayer.newest();
2034
const player = ruffle.createPlayer();
2135
containerRef.current.appendChild(player);
2236

23-
player.load(props.activeData?.launchCommand);
24-
console.log('Ruffle player created and loaded with:', props.activeData?.launchCommand);
37+
player.load(lc);
38+
console.log('Ruffle player created and loaded with:', lc);
2539
} catch (err) {
2640
console.error('Failed to create Ruffle player:', err);
2741
}
@@ -31,15 +45,16 @@ export default function LauncherEmbedPage(props: GameLaunchInfo) {
3145
document.head.append(elem);
3246
console.log('Patched in Ruffle');
3347
} else if (containerRef.current && (window as any).RufflePlayer) {
48+
const lc = props.activeData?.launchCommand;
3449
try {
3550
// Clear any existing content
3651
containerRef.current.innerHTML = '';
3752

3853
const ruffle = (window as any).RufflePlayer.newest();
3954
const player = ruffle.createPlayer();
4055
containerRef.current.appendChild(player);
41-
player.load(props.activeData?.launchCommand);
42-
console.log('Ruffle player created and loaded with:', props.activeData?.launchCommand);
56+
player.load(lc);
57+
console.log('Ruffle player created and loaded with:', lc);
4358
} catch (err) {
4459
console.error('Failed to create Ruffle player:', err);
4560
}
@@ -53,7 +68,7 @@ export default function LauncherEmbedPage(props: GameLaunchInfo) {
5368
return <div className='ruffle-page'>
5469
<div className='ruffle-wrapper'>
5570
<div className='ruffle-title'>{props.game.title}</div>
56-
<div className='ruffle-container' ref={containerRef}></div>
71+
<div className='ruffle-container' style={{ width, height }} ref={containerRef}></div>
5772
</div>
5873
<button className='simple-button' onClick={onBack}>Back</button>
5974
</div>;

extensions/core-ruffle/src/extension.ts

Lines changed: 17 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -86,18 +86,23 @@ export async function activate(context: flashpoint.ExtensionContext): Promise<vo
8686

8787
if (supportedEnabled || curation) {
8888
if (launchInfo.game.ruffleSupport.toLowerCase() === 'standalone') {
89-
flashpoint.log.info('Using Standalone Ruffle for supported game...');
90-
const defaultConfig = standaloneMiddleware.getDefaultConfig(launchInfo.game);
91-
standaloneMiddleware.execute(launchInfo, {
92-
middlewareId: '',
93-
name: '',
94-
enabled: true,
95-
version: defaultConfig.version,
96-
config: defaultConfig.config,
97-
});
98-
return;
99-
} else if (launchInfo.game.ruffleSupport.toLowerCase() === 'launcher') {
100-
launchInfo.launchInfo.component = 'ruffle/LauncherEmbedPage';
89+
const useLauncherEmbed = flashpoint.getExtConfigValue('com.ruffle.use-launcher-embed');
90+
if (useLauncherEmbed) {
91+
flashpoint.log.info('Using Launcher Embed Ruffle for supported game...');
92+
launchInfo.launchInfo.component = 'ruffle/LauncherEmbedPage';
93+
return;
94+
} else {
95+
flashpoint.log.info('Using Standalone Ruffle for supported game...');
96+
const defaultConfig = standaloneMiddleware.getDefaultConfig(launchInfo.game);
97+
standaloneMiddleware.execute(launchInfo, {
98+
middlewareId: '',
99+
name: '',
100+
enabled: true,
101+
version: defaultConfig.version,
102+
config: defaultConfig.config,
103+
});
104+
return;
105+
}
101106
} else if (launchInfo.game.ruffleSupport.toLowerCase() === 'webhosted') {
102107
flashpoint.log.info('Using Web Embed Ruffle for supported game...');
103108
const defaultConfig = webEmbedMiddleware.getDefaultConfig(launchInfo.game);

extensions/core-ruffle/static/ruffle.css

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,3 +25,8 @@
2525
margin: auto;
2626
box-shadow: 0 0 20px rgba(245, 245, 245, 0.4);
2727
}
28+
29+
ruffle-player {
30+
width: 100%;
31+
height: 100%;
32+
}

gulpfile.js

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -203,8 +203,7 @@ async function watchRenderer() {
203203
const config = await loadConfig();
204204
const rsbuild = await createRsbuild({
205205
rsbuildConfig: {
206-
...config.content,
207-
mode: 'development'
206+
...config.content
208207
}
209208
});
210209
await rsbuild.build({

src/renderer/components/CurateBox.tsx

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -606,9 +606,6 @@ export function CurateBox(props: CurateBoxProps) {
606606
}, {
607607
key: 'standalone',
608608
value: 'Standalone'
609-
}, {
610-
key: 'launcher',
611-
value: 'Launcher Embed'
612609
}]}
613610
warned={false}
614611
property='ruffleSupport'

src/renderer/components/RightBrowseSidebar.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import * as remote from '@electron/remote';
22
import { WithConfirmDialogProps } from '@renderer/containers/withConfirmDialog';
33
import { LangContext } from '@renderer/util/lang';
4-
import { ArchiveState, BackIn, BackOut, BackOutTemplate } from '@shared/back/types';
4+
import { ArchiveState, BackIn } from '@shared/back/types';
55
import { LOGOS, SCREENSHOTS } from '@shared/constants';
66
import { GamePropSuggestions, PickType, ProcessAction } from '@shared/interfaces';
77
import { generateTagFilterGroup, sizeToString } from '@shared/Util';

src/renderer/components/SearchBar.tsx

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -279,9 +279,6 @@ export function SearchBar() {
279279
}, {
280280
value: 'standalone',
281281
orderVal: 'Standalone'
282-
}, {
283-
value: 'launcher',
284-
orderVal: 'Launcher Embed',
285282
}];
286283
const tagItems = search.dropdowns.tags ? search.dropdowns.tags.map(tag => {
287284
const categoryId = tag.category ? categoryOrder.indexOf(tag.category) : 99999;

0 commit comments

Comments
 (0)