diff --git a/README.md b/README.md
index 2facd8e..e22a792 100644
--- a/README.md
+++ b/README.md
@@ -9,7 +9,7 @@ The goal is to encourage the ROM hacking community to modify the game and create
This app only works with Maniac Mansion on NES, it won't work with SCUMM files from other platforms or other NES games.
-Some of the code comes from the [ScummVM](https://github.com/scummvm) project.
+Portion of the code comes from [ScummVM](https://github.com/scummvm) and [Maniac Mansion Decoded](https://github.com/gzip/nes-6502-maniac-mansion-decoded).
## What does it do?
diff --git a/src/components/PaletteSelector.js b/src/components/PaletteSelector.js
index d78c01d..d65689d 100644
--- a/src/components/PaletteSelector.js
+++ b/src/components/PaletteSelector.js
@@ -1,4 +1,4 @@
-import { RadioGroup } from '@headlessui/react';
+import { RadioGroup, Label, Description } from '@headlessui/react';
import { CheckCircleIcon } from '@heroicons/react/20/solid';
import { clsx } from 'clsx';
@@ -11,83 +11,82 @@ const PaletteSelector = ({ palette, paletteOptions, setPalette }) => {
-
- {paletteOptions.map((palette) => (
-
- clsx(
- active
- ? 'border-primary-600 ring-2 ring-primary-600'
- : 'border-gray-300 dark:border-gray-700',
- 'relative flex cursor-pointer flex-col gap-4 rounded-lg border bg-slate-200 p-4 text-slate-900 shadow-sm hover:bg-slate-200/50 focus:outline-none dark:bg-slate-800 dark:text-slate-100 hover:dark:bg-slate-800/50',
- )
- }>
- {({ checked, active }) => (
- <>
-
-
-
-
- {palette.name}
-
-
-
-
-
-
-
-
-
- {palette.description}
-
-
+ onChange={setPalette}
+ className="flex flex-wrap gap-4 pl-8 md:gap-5 xl:gap-6">
+ {paletteOptions.map((option) => (
+
+ clsx(
+ focus
+ ? 'border-primary-600 ring-2 ring-primary-600'
+ : 'border-slate-300 dark:border-slate-700',
+ 'relative flex cursor-pointer flex-col gap-4 rounded-lg border bg-slate-200 p-4 text-slate-900 shadow-sm hover:bg-slate-200/50 focus:outline-none dark:bg-slate-800 dark:text-slate-100 hover:dark:bg-slate-800/50',
+ )
+ }>
+ {({ focus, checked }) => (
+ <>
+
+
+
+
+ {option.name}
+
+
+
+
+
+
+
+
+
+ {option.description}
+
-
-
-
-
-
- >
- )}
-
- ))}
-
+
+
+
+
+
+ >
+ )}
+
+ ))}
>
);
diff --git a/src/components/Room.js b/src/components/Room.js
index 5c9b147..705bde7 100644
--- a/src/components/Room.js
+++ b/src/components/Room.js
@@ -1,5 +1,3 @@
-import MainHeader from './MainHeader';
-import ResourceMetadata from './ResourceMetadata';
import ScreenCanvasContainer from '../containers/ScreenCanvasContainer';
import HoveredObjects from './HoveredObjects';
@@ -18,9 +16,6 @@ const Room = ({
return (
<>
-
-
-
diff --git a/src/components/RoomsList.js b/src/components/RoomsList.js
deleted file mode 100644
index 40446a6..0000000
--- a/src/components/RoomsList.js
+++ /dev/null
@@ -1,30 +0,0 @@
-import ColumnListHeader from './ColumnListHeader';
-import ColumnListItem from './ColumnListItem';
-
-const RoomsList = ({ items, currentId }) => {
- return (
- <>
-
Rooms
- {items.map(({ metadata, header }) => {
- if (!header) {
- // Some rooms are empty.
- return null;
- }
-
- const selected = metadata.id === currentId;
- const path = `/rooms/${metadata.id}`;
- const label = `Room ${metadata.id}`;
-
- return (
-
- {label}
-
- );
- })}
- >
- );
-};
-
-export default RoomsList;
diff --git a/src/components/ScreenNamesSelector.js b/src/components/ScreenNamesSelector.js
new file mode 100644
index 0000000..0e5a781
--- /dev/null
+++ b/src/components/ScreenNamesSelector.js
@@ -0,0 +1,67 @@
+import {
+ Field,
+ Label,
+ Description,
+ Radio,
+ RadioGroup,
+} from '@headlessui/react';
+import { clsx } from 'clsx';
+
+const ScreenNamesSelector = ({
+ screenName,
+ screenNameOptions,
+ setScreenName,
+}) => {
+ return (
+ <>
+
+ Screen names
+
+
+
+ {screenNameOptions.map((option) => (
+
+
+ {({ focus, checked }) => (
+
+
+
+
+
+
+ {option.name}
+
+
+ {option.description}
+
+
+
+ )}
+
+
+ ))}
+
+ >
+ );
+};
+
+export default ScreenNamesSelector;
diff --git a/src/components/ScreenSelector.js b/src/components/ScreenSelector.js
index ae36355..23c5756 100644
--- a/src/components/ScreenSelector.js
+++ b/src/components/ScreenSelector.js
@@ -9,11 +9,12 @@ import {
} from '@headlessui/react';
import { CheckIcon, ChevronUpDownIcon } from '@heroicons/react/20/solid';
import { clsx } from 'clsx';
+import getScreenLabel from '../lib/getScreenLabel';
const getScreenNameFromPathname = (pathname) => {
const id = pathname.split('/').pop();
const screenType = pathname.startsWith('/rooms/') ? 'room' : 'title';
- return screenType === 'title' ? `Title screen ${id}` : `Room ${id}`;
+ return getScreenLabel(screenType, id);
};
const ScreenSelector = ({ rooms, titles }) => {
@@ -72,7 +73,7 @@ const ScreenSelector = ({ rooms, titles }) => {
selected ? 'font-semibold' : 'font-normal',
'block truncate',
)}>
- {`Title screen ${metadata.id}`}
+ {getScreenLabel('title', metadata.id)}
{selected ? (
@@ -117,7 +118,7 @@ const ScreenSelector = ({ rooms, titles }) => {
selected ? 'font-semibold' : 'font-normal',
'block truncate',
)}>
- {`Room ${metadata.id}`}
+ {getScreenLabel('room', metadata.id)}
{selected ? (
diff --git a/src/components/ThemeSwitcher.js b/src/components/ThemeSwitcher.js
index 137a247..ed435ad 100644
--- a/src/components/ThemeSwitcher.js
+++ b/src/components/ThemeSwitcher.js
@@ -1,4 +1,4 @@
-import { RadioGroup } from '@headlessui/react';
+import { RadioGroup, Label } from '@headlessui/react';
import { clsx } from 'clsx';
const ThemeSwitcher = ({ theme, setTheme, themeOptions }) => {
@@ -10,27 +10,25 @@ const ThemeSwitcher = ({ theme, setTheme, themeOptions }) => {
- Choose a theme
-
- {themeOptions.map((option) => (
-
- clsx(
- active && 'ring-2 ring-primary-600 ring-offset-2',
- checked
- ? 'bg-primary-600 text-slate-100 hover:bg-primary-500'
- : 'bg-slate-200 text-slate-900 ring-1 ring-inset ring-slate-300 hover:bg-slate-200/50 dark:bg-slate-800 dark:text-slate-100 dark:ring-slate-700 hover:dark:bg-slate-800/50',
- 'cursor-pointer focus:outline-none',
- 'flex w-48 max-w-48 flex-initial items-center justify-center rounded-md px-3 py-3 text-sm font-semibold sm:flex-1',
- )
- }>
- {option.name}
-
- ))}
-
+ onChange={setTheme}
+ className="flex gap-4 pl-8 md:gap-5 xl:gap-6">
+ {themeOptions.map((option) => (
+
+ clsx(
+ focus && 'ring-2 ring-primary-600 ring-offset-2',
+ checked
+ ? 'bg-primary-600 text-slate-100 hover:bg-primary-500'
+ : 'bg-slate-200 text-slate-900 ring-1 ring-inset ring-slate-300 hover:bg-slate-200/50 dark:bg-slate-800 dark:text-slate-100 dark:ring-slate-700 hover:dark:bg-slate-800/50',
+ 'cursor-pointer focus:outline-none',
+ 'flex w-48 max-w-48 flex-initial items-center justify-center rounded-md px-3 py-3 text-sm font-medium sm:flex-1',
+ )
+ }>
+ {option.name}
+
+ ))}
>
);
diff --git a/src/components/TitlesList.js b/src/components/TitlesList.js
deleted file mode 100644
index 14b56db..0000000
--- a/src/components/TitlesList.js
+++ /dev/null
@@ -1,25 +0,0 @@
-import ColumnListHeader from './ColumnListHeader';
-import ColumnListItem from './ColumnListItem';
-
-const TitlesList = ({ items, currentId }) => {
- return (
- <>
-
Titles
- {items.map(({ metadata }) => {
- const selected = metadata.id === currentId;
- const path = `/titles/${metadata.id}`;
- const label = `Title ${metadata.id}`;
-
- return (
-
- {label}
-
- );
- })}
- >
- );
-};
-
-export default TitlesList;
diff --git a/src/containers/RoomsContainer.js b/src/containers/RoomsContainer.js
index 29a183c..b50ad16 100644
--- a/src/containers/RoomsContainer.js
+++ b/src/containers/RoomsContainer.js
@@ -1,6 +1,7 @@
import { useState, useEffect } from 'react';
import { useParams } from 'react-router-dom';
import { useRomDispatch } from '../contexts/RomContext';
+import getScreenLabel from '../lib/getScreenLabel';
import PrimaryColumn from '../components/PrimaryColumn';
import Main from '../components/Main';
import ScreenSelector from '../components/ScreenSelector';
@@ -12,6 +13,8 @@ import RoomTabs from '../components/RoomTabs';
import Palettes from '../components/Palettes';
import RoomGfx from '../components/RoomGfx';
import RoomScripts from '../components/RoomScripts';
+import MainHeader from '../components/MainHeader';
+import ResourceMetadata from '../components/ResourceMetadata';
const RoomsContainer = ({ rooms, titles, roomgfx, globdata }) => {
const dispatch = useRomDispatch();
@@ -118,6 +121,9 @@ const RoomsContainer = ({ rooms, titles, roomgfx, globdata }) => {
Rooms
) : (
<>
+
+
+
{
// Find the options set, or the default ones.
const selectedThemeValue = localStorage.getItem('theme');
@@ -50,8 +65,14 @@ const SettingsContainer = () => {
paletteOptions.find(({ value }) => value === selectedPaletteValue) ||
paletteOptions.find(({ defaultOption }) => defaultOption);
+ const selectedScreenNameValue = localStorage.getItem('screen-name');
+ const selectedScreenName =
+ screenNameOptions.find(({ value }) => value === selectedScreenNameValue) ||
+ screenNameOptions.find(({ defaultOption }) => defaultOption);
+
const [theme, setTheme] = useState(selectedTheme);
const [palette, setPalette] = useState(selectedPalette);
+ const [screenName, setScreenName] = useState(selectedScreenName);
// Keep the local storage and the DOM in sync with the state.
const setThemeWrapper = (theme) => {
@@ -78,6 +99,17 @@ const SettingsContainer = () => {
localStorage.setItem('palette', palette.value);
};
+ const setScreenNameWrapper = (screenName) => {
+ setScreenName(screenName);
+
+ if (screenName.defaultOption) {
+ localStorage.removeItem('screen-name');
+ return;
+ }
+
+ localStorage.setItem('screen-name', screenName.value);
+ };
+
return (
@@ -91,6 +123,11 @@ const SettingsContainer = () => {
paletteOptions={paletteOptions}
setPalette={setPaletteWrapper}
/>
+
);
};
diff --git a/src/containers/TitlesContainer.js b/src/containers/TitlesContainer.js
index 6b78ce1..ca83732 100644
--- a/src/containers/TitlesContainer.js
+++ b/src/containers/TitlesContainer.js
@@ -1,6 +1,7 @@
import { useState, useEffect } from 'react';
import { useParams } from 'react-router-dom';
import { useRomDispatch } from '../contexts/RomContext';
+import getScreenLabel from '../lib/getScreenLabel';
import PrimaryColumn from '../components/PrimaryColumn';
import Main from '../components/Main';
import ScreenSelector from '../components/ScreenSelector';
@@ -68,7 +69,8 @@ const TitlesContainer = ({ rooms, titles }) => {
Titles
) : (
<>
-
+
{
+ switch (localStorage.getItem('screen-name')) {
+ default:
+ case 'mm':
+ if (screenType === 'title') {
+ if (long) {
+ return `Title screen ${id} - ${titleNames[id]}`;
+ }
+ return `${id} ${titleNames[id]}`;
+ }
+
+ if (screenType === 'room') {
+ if (long) {
+ return `Room ${zeroPad(id)} - ${roomNames[id]}`;
+ }
+ return `${id} ${roomNames[id]}`;
+ }
+
+ throw new Error(`Unknown screen type ${screenType}`);
+
+ case 'numbers':
+ if (screenType === 'title') {
+ return `Title screen ${id}`;
+ }
+
+ if (screenType === 'room') {
+ if (long) {
+ return `Room ${zeroPad(id)}`;
+ }
+ return `Room ${id}`;
+ }
+
+ throw new Error(`Unknown screen type ${screenType}`);
+ }
+};
+
+export default getScreenLabel;