@wasm-gaming/fbneo-wasm 0.1.2 → 0.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (59) hide show
  1. package/README.md +112 -69
  2. package/dist/fbneo/app/app.css +112 -0
  3. package/dist/fbneo/app/app.js +646 -0
  4. package/dist/fbneo/engine-specs.js +646 -0
  5. package/dist/fbneo/fbneo.js +2 -0
  6. package/dist/fbneo/fbneo.options.d.ts +72 -19
  7. package/dist/fbneo/fbneo.options.d.ts.map +1 -1
  8. package/dist/fbneo/fbneo.options.js +49 -48
  9. package/dist/fbneo/fbneo.options.js.map +1 -1
  10. package/dist/fbneo/fbneo.sdk.d.ts +157 -8
  11. package/dist/fbneo/fbneo.sdk.d.ts.map +1 -1
  12. package/dist/fbneo/fbneo.sdk.js +641 -181
  13. package/dist/fbneo/fbneo.sdk.js.map +1 -1
  14. package/dist/fbneo/fbneo.wasm +4 -0
  15. package/dist/fbneo/romset.d.ts +0 -0
  16. package/dist/fbneo/romset.d.ts.map +1 -1
  17. package/dist/fbneo/romset.js.map +1 -1
  18. package/{data → dist/fbneo}/romsets/atari.json +5036 -118
  19. package/{data → dist/fbneo}/romsets/capcom.json +3392 -848
  20. package/{data → dist/fbneo}/romsets/cave.json +460 -115
  21. package/{data → dist/fbneo}/romsets/channelf.json +200 -50
  22. package/{data → dist/fbneo}/romsets/coleco.json +2650 -658
  23. package/{data → dist/fbneo}/romsets/cps3.json +240 -60
  24. package/{data → dist/fbneo}/romsets/dataeast.json +1352 -338
  25. package/{data → dist/fbneo}/romsets/galaxian.json +1192 -298
  26. package/dist/fbneo/romsets/gba.json +197 -0
  27. package/{data → dist/fbneo}/romsets/index.json +16 -12
  28. package/{data → dist/fbneo}/romsets/irem.json +796 -199
  29. package/{data → dist/fbneo}/romsets/konami.json +1644 -411
  30. package/{data → dist/fbneo}/romsets/megadrive.json +11899 -2926
  31. package/{data → dist/fbneo}/romsets/midway.json +560 -140
  32. package/{data → dist/fbneo}/romsets/msx.json +7204 -1798
  33. package/{data → dist/fbneo}/romsets/neogeo.json +2704 -614
  34. package/{data → dist/fbneo}/romsets/nes.json +12815 -3155
  35. package/{data → dist/fbneo}/romsets/pce.json +1952 -488
  36. package/{data → dist/fbneo}/romsets/pgm.json +796 -199
  37. package/{data → dist/fbneo}/romsets/pgm2.json +32 -8
  38. package/{data → dist/fbneo}/romsets/pre90s.json +10002 -2084
  39. package/{data → dist/fbneo}/romsets/psikyo.json +160 -40
  40. package/{data → dist/fbneo}/romsets/pst90s.json +6400 -1597
  41. package/{data → dist/fbneo}/romsets/sega.json +2756 -658
  42. package/{data → dist/fbneo}/romsets/sg1000.json +1032 -255
  43. package/{data → dist/fbneo}/romsets/sms.json +6012 -1503
  44. package/{data → dist/fbneo}/romsets/snes.json +10991 -2816
  45. package/{data → dist/fbneo}/romsets/spectrum.json +13579 -3361
  46. package/{data → dist/fbneo}/romsets/taito.json +2496 -624
  47. package/{data → dist/fbneo}/romsets/toaplan.json +576 -144
  48. package/package.json +10 -15
  49. package/src/app/app.css +112 -0
  50. package/src/app/app.js +646 -0
  51. package/src/fbneo.options.ts +119 -63
  52. package/src/fbneo.sdk.ts +712 -211
  53. package/src/romset.ts +0 -0
  54. package/dist/fbneo/fbneo.manifest.d.ts +0 -4
  55. package/dist/fbneo/fbneo.manifest.d.ts.map +0 -1
  56. package/dist/fbneo/fbneo.manifest.js +0 -33
  57. package/dist/fbneo/fbneo.manifest.js.map +0 -1
  58. package/dist/manifest.json +0 -91
  59. package/src/fbneo.manifest.ts +0 -38
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@wasm-gaming/fbneo-wasm",
3
- "version": "0.1.2",
4
- "description": "FBNeo (FinalBurn Neo arcade emulator) compiled to WebAssembly via Emscripten, with a JS SDK conforming to the wasm-gaming engine contract.",
3
+ "version": "0.3.0",
4
+ "description": "FBNeo (FinalBurn Neo arcade emulator) compiled to WebAssembly, with a self-contained JS SDK implementing the wasm-gaming engine contract.",
5
5
  "repository": {
6
6
  "type": "git",
7
7
  "url": "git+https://github.com/wasm-gaming/fbneo-wasm.git"
@@ -18,6 +18,9 @@
18
18
  "types": "./dist/fbneo/fbneo.options.d.ts",
19
19
  "import": "./dist/fbneo/fbneo.options.js"
20
20
  },
21
+ "./app": {
22
+ "import": "./dist/fbneo/app/app.js"
23
+ },
21
24
  "./romset": {
22
25
  "types": "./dist/fbneo/romset.d.ts",
23
26
  "import": "./dist/fbneo/romset.js"
@@ -26,14 +29,11 @@
26
29
  "types": "./dist/fbneo/neo.d.ts",
27
30
  "import": "./dist/fbneo/neo.js"
28
31
  },
29
- "./romsets/*": "./data/romsets/*",
30
- "./manifest": "./dist/manifest.json"
32
+ "./romsets/*": "./dist/fbneo/romsets/*"
31
33
  },
32
34
  "files": [
33
35
  "dist/fbneo/",
34
- "dist/manifest.json",
35
- "data/romsets/",
36
- "src/fbneo.manifest.ts",
36
+ "src/app/",
37
37
  "src/fbneo.options.ts",
38
38
  "src/fbneo.sdk.ts",
39
39
  "src/romset.ts",
@@ -42,16 +42,11 @@
42
42
  ],
43
43
  "comment:scripts": "Build logic lives in the Makefile, not here (make build / build-sdk / build-wasm / preview).",
44
44
  "scripts": {},
45
- "peerDependencies": {
46
- "@wasm-gaming/engine-specs": "*"
47
- },
48
- "peerDependenciesMeta": {
49
- "@wasm-gaming/engine-specs": {
50
- "optional": true
51
- }
45
+ "comment:dependencies": "engine-specs is the one wasm-gaming package an engine depends on. Its runtime is also copied into dist/fbneo/ and imported relatively, so the built SDK loads without a bundler or an import map; the dependency carries the types.",
46
+ "dependencies": {
47
+ "@wasm-gaming/engine-specs": "^0.4.0"
52
48
  },
53
49
  "devDependencies": {
54
- "@wasm-gaming/engine-specs": "^0.2.3",
55
50
  "typescript": "^5.5.0"
56
51
  },
57
52
  "engineContract": "https://github.com/wasm-gaming/engine-specs",
@@ -0,0 +1,112 @@
1
+ /* FBNeo app — suspend points (Classic Mini style) and the pause menu.
2
+ engine-specs `--wg-*` tokens when the host sets them; same values as fallbacks. */
3
+
4
+ .fbn-app {
5
+ --ring: var(--wg-focus-ring, 0 0 0 3px #fff);
6
+ --surface: var(--wg-surface, rgb(18 20 28 / 0.78));
7
+ --line: var(--wg-line, rgb(255 255 255 / 0.12));
8
+ --text: var(--wg-text, #f4f6fb);
9
+ --muted: var(--wg-muted, #8e97a9);
10
+ --danger: var(--wg-danger, #f87171);
11
+ --ui: var(--wg-font-ui, 'Inter Variable', 'Inter', system-ui, sans-serif);
12
+ --display: var(--wg-font-display, 'Unbounded Variable', 'Unbounded', system-ui, sans-serif);
13
+ --ease: var(--wg-ease, cubic-bezier(0.2, 0.8, 0.2, 1));
14
+ position: absolute; inset: 0; overflow: hidden; background: #000; color: var(--text);
15
+ font-family: var(--ui); user-select: none; -webkit-tap-highlight-color: transparent;
16
+ }
17
+ .fbn-app * { box-sizing: border-box; }
18
+ .fbn-stage { position: absolute; inset: 0; display: grid; place-items: center; }
19
+ .fbn-stage canvas { outline: none; }
20
+ .fbn-overlay { position: absolute; inset: 0; display: grid; place-items: center; pointer-events: none; }
21
+ .fbn-overlay > * { pointer-events: auto; }
22
+ .fbn-app:not([data-screen='game']) .fbn-overlay {
23
+ background:
24
+ radial-gradient(120% 80% at 50% 0%, color-mix(in srgb, var(--accent) 34%, transparent), transparent 70%),
25
+ rgb(4 6 12 / 0.74);
26
+ backdrop-filter: blur(14px) saturate(1.2);
27
+ -webkit-backdrop-filter: blur(14px) saturate(1.2);
28
+ }
29
+ .fbn-app[data-screen='boot'] .fbn-overlay,
30
+ .fbn-app[data-screen='points'] .fbn-overlay { background-color: rgb(4 6 12 / 0.9); }
31
+
32
+ .kicker { margin: 0; font: 600 0.72rem var(--ui); letter-spacing: 0.22em; text-transform: uppercase; color: var(--muted); }
33
+ .fbn-app h2 { margin: 0; font: 700 clamp(1.3rem, 3vw, 2rem) var(--display); letter-spacing: -0.02em; }
34
+
35
+ /* boot */
36
+ .fbn-boot { display: grid; justify-items: center; gap: 22px; }
37
+ .fbn-boot img { width: min(240px, 46vw); border-radius: 22px; box-shadow: 0 30px 80px -30px #000; animation: fbn-breathe 2.4s var(--ease) infinite alternate; }
38
+ .fbn-boot p { margin: 0; color: var(--muted); font-weight: 500; }
39
+ @keyframes fbn-breathe { from { opacity: 0.55; transform: scale(0.98); } to { opacity: 1; transform: none; } }
40
+
41
+ /* suspend points: a row of frames, like the Classic Mini's */
42
+ .fbn-points { width: min(1180px, 100%); padding: 0 clamp(16px, 4vw, 48px); display: grid; gap: clamp(20px, 4vh, 36px); }
43
+ .fbn-points header { display: grid; gap: 6px; }
44
+ .points { display: flex; justify-content: center; gap: clamp(10px, 1.4vw, 18px); padding: 12px 4px; }
45
+ .point {
46
+ all: unset; box-sizing: border-box; flex: 0 1 196px; min-width: 0; display: grid; gap: 8px; cursor: pointer;
47
+ transition: transform 0.22s var(--ease), opacity 0.2s;
48
+ }
49
+ .point-frame {
50
+ position: relative; display: grid; place-items: center; aspect-ratio: 320 / 224; border-radius: 10px; overflow: hidden;
51
+ background: rgb(255 255 255 / 0.04); border: 2px solid rgb(255 255 255 / 0.16);
52
+ transition: box-shadow 0.22s var(--ease), border-color 0.2s;
53
+ }
54
+ .point-frame img { width: 100%; height: 100%; object-fit: cover; image-rendering: pixelated; }
55
+ .point-frame svg { width: 30%; color: var(--muted); }
56
+ .point.is-empty .point-frame { border-style: dashed; background: transparent; }
57
+ .point.is-auto .point-frame { border-color: color-mix(in srgb, var(--accent) 70%, #fff); }
58
+ .point-label { font: 700 0.9rem var(--ui); text-align: center; }
59
+ .point.is-auto .point-label { color: #fda4af; }
60
+ .point-date { font: 500 0.74rem var(--ui); color: var(--muted); text-align: center; font-variant-numeric: tabular-nums; }
61
+ .point-lock {
62
+ position: absolute; top: 6px; right: 6px; display: grid; place-items: center; width: 24px; height: 24px; border-radius: 50%;
63
+ background: rgb(0 0 0 / 0.72); color: #fbbf24;
64
+ }
65
+ .point-lock svg { width: 13px; color: inherit; }
66
+ .point.is-start .point-frame { border-style: solid; }
67
+ .point.is-focused { transform: translateY(-6px) scale(1.04); }
68
+ .point.is-focused .point-frame { box-shadow: var(--ring), 0 26px 60px -24px #000; border-color: transparent; }
69
+ .point.is-dim { opacity: 0.32; }
70
+ .point.is-target.is-focused .point-frame { box-shadow: 0 0 0 3px #fbbf24, 0 26px 60px -24px #000; }
71
+
72
+ /* pause, sheets, confirms */
73
+ .fbn-panel {
74
+ width: min(440px, 92vw); display: grid; gap: 10px; padding: 26px; border-radius: 28px;
75
+ background: rgb(20 22 31 / 0.92); border: 1px solid var(--line); box-shadow: 0 40px 100px -30px #000;
76
+ }
77
+ .fbn-panel.is-small { width: min(380px, 92vw); }
78
+ .fbn-panel h2 { margin-bottom: 8px; }
79
+ .fbn-panel .text { margin: 0 0 8px; color: var(--muted); line-height: 1.5; }
80
+ .item {
81
+ all: unset; box-sizing: border-box; display: grid; gap: 2px; padding: 13px 16px; border-radius: 14px;
82
+ background: rgb(255 255 255 / 0.05); font-weight: 600; cursor: pointer; transition: background 0.15s, box-shadow 0.15s;
83
+ }
84
+ .item small { font-weight: 500; font-size: 0.78rem; color: var(--muted); }
85
+ .item[disabled] { opacity: 0.45; cursor: default; }
86
+ .item.is-focused { background: #fff; color: #0b0d12; box-shadow: var(--ring); }
87
+ .item.is-focused small { color: #4b5563; }
88
+ .item.is-danger.is-focused { background: var(--danger); color: #1a0505; box-shadow: 0 0 0 3px var(--danger); }
89
+ .item.is-danger.is-focused small { color: #450a0a; }
90
+ .fbn-panel .row { display: grid; grid-template-columns: 1fr 1fr; gap: 10px; }
91
+ .fbn-panel .row .item { text-align: center; }
92
+ .fbn-layer { position: absolute; inset: 0; display: grid; place-items: center; background: rgb(0 0 0 / 0.55); }
93
+
94
+ .fbn-hints { display: flex; flex-wrap: wrap; gap: 8px 18px; justify-content: center; color: var(--muted); font-size: 0.78rem; font-weight: 500; }
95
+ .fbn-hints span { display: inline-flex; align-items: center; gap: 7px; }
96
+ .fbn-hints kbd { display: inline-grid; place-items: center; min-width: 22px; height: 22px; padding: 0 6px; border-radius: 11px; background: rgb(255 255 255 / 0.12); color: var(--text); font: 700 0.68rem var(--ui); }
97
+ .fbn-panel .fbn-hints { justify-content: flex-start; margin-top: 6px; }
98
+
99
+ .fbn-toast {
100
+ position: absolute; left: 50%; bottom: calc(28px + var(--wg-safe-bottom, 0px)); transform: translateX(-50%); margin: 0;
101
+ padding: 10px 18px; border-radius: 999px; background: rgb(20 22 31 / 0.94); border: 1px solid var(--line);
102
+ font-weight: 600; font-size: 0.85rem; white-space: nowrap; animation: fbn-toast 0.3s var(--ease);
103
+ }
104
+ @keyframes fbn-toast { from { opacity: 0; transform: translate(-50%, 8px); } }
105
+
106
+ @media (max-width: 960px) {
107
+ .points { justify-content: flex-start; overflow-x: auto; scrollbar-width: none; padding: 14px 6px 18px; }
108
+ .point { flex: 0 0 min(42vw, 180px); }
109
+ }
110
+ @media (prefers-reduced-motion: reduce) {
111
+ .point, .point-frame, .fbn-boot img, .fbn-toast { transition: none; animation: none; }
112
+ }