From 64bdd2db70d421b592065f5feeeea0f91563ce8a Mon Sep 17 00:00:00 2001 From: edo999 Date: Sat, 25 May 2024 16:48:14 +0100 Subject: [PATCH] =?UTF-8?q?Generate=20ROM=20hacks=20with=20modified=20pale?= =?UTF-8?q?ttes=20=F0=9F=92=A5.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 11 +-- experiments/relocateNtAttrs.js | 5 +- experiments/updatePreps.js | 3 +- package.json | 4 +- src/App.js | 40 ++------- src/components/DownloadRom.js | 51 +++++++++++ src/components/Footer.js | 72 +++++++-------- src/components/Header.js | 21 ++++- src/components/Layout.js | 20 ++--- src/containers/DropZoneContainer.js | 31 ++++--- src/containers/ResourceExplorer.js | 7 +- src/containers/RoomsContainer.js | 16 +++- src/containers/TitlesContainer.js | 16 +++- src/contexts/RomContext.js | 50 +++++++++++ src/index.js | 13 ++- src/lib/cliUtils.js | 69 +-------------- src/lib/parser/parseRom.js | 4 +- src/lib/resources.js | 16 ++-- src/lib/romUtils.js | 131 ++++++++++++++++++++++++++++ src/lib/serialiser/serialiser.js | 19 +++- src/lib/utils.js | 14 +-- 21 files changed, 407 insertions(+), 206 deletions(-) create mode 100644 src/components/DownloadRom.js create mode 100644 src/contexts/RomContext.js create mode 100644 src/lib/romUtils.js diff --git a/README.md b/README.md index 1b245ac..915f6f0 100644 --- a/README.md +++ b/README.md @@ -1,13 +1,13 @@ # SCUMM NES resource explorer -> An app to explore the content of the Maniac Mansion game on NES. +> An app to explore and modify the content of the Maniac Mansion game on NES. ## What is this? -This tool is a web app to explore the resources from the Maniac Mansion game on NES. +This tool is a web app to explore and modify the resources contained in the Maniac Mansion game on NES. The goal is to encourage the ROM hacking community to modify the game and create new hacks. -This app only works with Maniac Mansion on NES, it won't work with data files from other platforms or other games. +This app only works with Maniac Mansion on NES, it won't work with data files from other platforms or other NES games. Some of the code comes from the [ScummVM](https://github.com/scummvm) project. @@ -37,8 +37,6 @@ The Japanese version is not supported. The app doesn't use the runtime code used by the NES to start and play the game. It only works with the SCUMM resources stored in the ROM files. -It does not modify the ROM, it is only an explorer of the resources present in the game. - ## How to use it? On top of the app, there is a command line interface to export the resources to JSON. This is useful to do process or compare the data. @@ -82,9 +80,8 @@ Then deploy the content of the `dist` folder. - Use Typescript. - Write more tests. -- Parse more resource types (scripts, sounds...). +- Parse more resource types (sprites, sounds...). - QoF improvements (store the ROM files locally...) -- Enable modification of the resources to create new games. ### Out of scope for now diff --git a/experiments/relocateNtAttrs.js b/experiments/relocateNtAttrs.js index 70c31c6..940a860 100644 --- a/experiments/relocateNtAttrs.js +++ b/experiments/relocateNtAttrs.js @@ -2,7 +2,8 @@ import { parseArgs } from 'node:util'; import { basename } from 'node:path'; -import { loadRom, saveRom, expandRom, inject } from '../src/lib/cliUtils.js'; +import { loadRom, saveRom, expandRom } from '../src/lib/cliUtils.js'; +import { inject } from '../src/lib/romUtils.js'; import parseRoom from '../src/lib/parser/parseRooms.js'; import { zeroPad, hex } from '../src/lib/utils.js'; @@ -119,7 +120,7 @@ for (let i = 0; i < roomNum; i++) { nametableLength, hex(bankOffset + nametableLength, 4), hex(atOffset + headerLength), - attrsLength + attrsLength, ); bankOffset += nametableLength; bankOffset += attrsLength; diff --git a/experiments/updatePreps.js b/experiments/updatePreps.js index bb51231..ab15bb8 100644 --- a/experiments/updatePreps.js +++ b/experiments/updatePreps.js @@ -2,7 +2,8 @@ import { parseArgs } from 'node:util'; import { basename } from 'node:path'; -import { loadRom, saveRom, inject } from '../src/lib/cliUtils.js'; +import { loadRom, saveRom } from '../src/lib/cliUtils.js'; +import { inject } from '../src/lib/romUtils.js'; import serialisePreps from '../src/lib/serialiser/serialisePreps.js'; /* diff --git a/package.json b/package.json index 4c2d29f..0f4878a 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "scumm-nes", - "version": "0.1.2", - "description": "An app to explore the content of the Maniac Mansion game on NES.", + "version": "0.2.0", + "description": "An app to explore and modify the content of the Maniac Mansion game on NES.", "author": "edo999@gmail.com", "license": "BlueOak-1.0.0", "keywords": [ diff --git a/src/App.js b/src/App.js index f671ba9..1bb33b2 100644 --- a/src/App.js +++ b/src/App.js @@ -1,41 +1,19 @@ -import { useState } from 'react'; -import { ErrorBoundary } from 'react-error-boundary'; -import { useNavigate } from 'react-router-dom'; +import { useRom } from './contexts/RomContext'; import Layout from './components/Layout'; import DropZoneContainer from './containers/DropZoneContainer'; import ResourceExplorer from './containers/ResourceExplorer'; -import ErrorMessage from './components/ErrorMessage'; const App = () => { - const [rom, setRom] = useState(null); - const [res, setRes] = useState(null); - const [resources, setResources] = useState(null); - const navigate = useNavigate(); - - const onFile = async (rom, res) => { - const { default: parseRom } = await import('./lib/parser/parseRom'); - setRom(rom); - setRes(res); - setResources(parseRom(rom, res)); - - // Redirect to the first room. - navigate('/rooms/1'); - }; + const { prg, res, resources } = useRom(); return ( - - - {!rom || !res ? ( - - ) : ( - - )} - - + + {!prg || !res || !resources ? ( + + ) : ( + + )} + ); }; diff --git a/src/components/DownloadRom.js b/src/components/DownloadRom.js new file mode 100644 index 0000000..d19e038 --- /dev/null +++ b/src/components/DownloadRom.js @@ -0,0 +1,51 @@ +import { useRef, useState } from 'react'; +import { useRom } from '../contexts/RomContext'; +import { generateRomHackFile } from '../lib/romUtils'; + +const type = 'application/x-nes-rom'; +const fileName = 'mm-hack.nes'; + +const DownloadRom = ({ children }) => { + const { prg, resources } = useRom(); + const [aHref, setAHref] = useState(null); + const aRef = useRef(null); + + if (prg === null) { + return ( + + ); + } + + return ( + <> + + {/* eslint-disable-next-line jsx-a11y/anchor-has-content */} + + + ); +}; + +export default DownloadRom; diff --git a/src/components/Footer.js b/src/components/Footer.js index 3e6d738..32135bf 100644 --- a/src/components/Footer.js +++ b/src/components/Footer.js @@ -46,40 +46,40 @@ const navigation = [ }, ]; -export default function Footer() { - return ( - +); + +export default Footer; diff --git a/src/components/Header.js b/src/components/Header.js index 6b25eac..59eb6e1 100644 --- a/src/components/Header.js +++ b/src/components/Header.js @@ -1,5 +1,6 @@ import { Fragment, useState } from 'react'; import { Link } from 'react-router-dom'; +import DownloadRom from './DownloadRom'; import { Dialog, DialogPanel, @@ -7,6 +8,7 @@ import { TransitionChild, } from '@headlessui/react'; import { + ArrowDownTrayIcon, Cog8ToothIcon, Bars3Icon, XMarkIcon, @@ -22,7 +24,7 @@ const navigation = [ { name: 'Settings', href: '/settings', sideBarOnly: true }, ]; -export default function Header() { +const Header = () => { const [mobileMenuOpen, setMobileMenuOpen] = useState(false); return ( @@ -63,7 +65,13 @@ export default function Header() { ))} -
+
+ + + ))} + + + Download modified ROM + +
@@ -139,4 +152,6 @@ export default function Header() { ); -} +}; + +export default Header; diff --git a/src/components/Layout.js b/src/components/Layout.js index c4dd6a5..5a5eb14 100644 --- a/src/components/Layout.js +++ b/src/components/Layout.js @@ -1,14 +1,14 @@ import Header from './Header'; import Footer from './Footer'; -export default function Layout({ children }) { - return ( -
-
-
- {children} -
-