Restore CD-ROM settings tab behind a feature flag

The tab, file picker, and prop wiring are all back and styled to match
the new Properties sheet, gated on CDROM_ENABLED=false until v86's IDE
CD path works again.
This commit is contained in:
Felix Rieseberg
2026-04-11 09:01:29 -07:00
parent 80505384c6
commit 4ed96deecc
2 changed files with 67 additions and 2 deletions

View File

@@ -2,17 +2,22 @@ import * as React from "react";
import { resetState } from "./utils/reset-state"; import { resetState } from "./utils/reset-state";
// v86's IDE CD-ROM path is currently broken; flip this once it works again.
const CDROM_ENABLED = false;
interface CardSettingsProps { interface CardSettingsProps {
bootFromScratch: () => void; bootFromScratch: () => void;
setFloppy: (file: File) => void; setFloppy: (file: File) => void;
setCdrom: (file: File) => void;
setSmbSharePath: (path: string) => void; setSmbSharePath: (path: string) => void;
pickFolder: () => Promise<string | null>; pickFolder: () => Promise<string | null>;
navigate: (to: "start" | "settings") => void; navigate: (to: "start" | "settings") => void;
floppy?: File; floppy?: File;
cdrom?: File;
smbSharePath: string; smbSharePath: string;
} }
type Tab = "floppy" | "network" | "state"; type Tab = "floppy" | "cdrom" | "network" | "state";
interface CardSettingsState { interface CardSettingsState {
tab: Tab; tab: Tab;
@@ -27,6 +32,7 @@ export class CardSettings extends React.Component<
super(props); super(props);
this.onChangeFloppy = this.onChangeFloppy.bind(this); this.onChangeFloppy = this.onChangeFloppy.bind(this);
this.onChangeCdrom = this.onChangeCdrom.bind(this);
this.onResetState = this.onResetState.bind(this); this.onResetState = this.onResetState.bind(this);
this.state = { this.state = {
@@ -53,12 +59,14 @@ export class CardSettings extends React.Component<
<div className="window-body"> <div className="window-body">
<menu role="tablist"> <menu role="tablist">
{this.renderTab("floppy", "Floppy Drive")} {this.renderTab("floppy", "Floppy Drive")}
{CDROM_ENABLED && this.renderTab("cdrom", "CD-ROM")}
{this.renderTab("network", "Network Share")} {this.renderTab("network", "Network Share")}
{this.renderTab("state", "Machine State")} {this.renderTab("state", "Machine State")}
</menu> </menu>
<div className="window settings-panel" role="tabpanel"> <div className="window settings-panel" role="tabpanel">
<div className="window-body"> <div className="window-body">
{tab === "floppy" && this.renderFloppy()} {tab === "floppy" && this.renderFloppy()}
{tab === "cdrom" && this.renderCdrom()}
{tab === "network" && this.renderSmbShare()} {tab === "network" && this.renderSmbShare()}
{tab === "state" && this.renderState()} {tab === "state" && this.renderState()}
</div> </div>
@@ -131,6 +139,48 @@ export class CardSettings extends React.Component<
); );
} }
private renderCdrom() {
const { cdrom } = this.props;
return (
<fieldset>
<legend>Drive D:</legend>
<input
id="cdrom-input"
type="file"
onChange={this.onChangeCdrom}
style={{ display: "none" }}
/>
<div className="settings-row">
<img className="settings-icon" src="../../static/cdrom.png" />
<p>
windows95 ships with a virtual CD-ROM drive. Mount an{" "}
<code>.iso</code> image here, then boot the machine to read it from
inside Windows.
</p>
</div>
<div className="field-row-stacked">
<label htmlFor="cdrom-path">Mounted image</label>
<input
id="cdrom-path"
type="text"
readOnly
value={cdrom ? cdrom.name : "(No disc in drive)"}
/>
</div>
<div className="settings-buttons">
<button
onClick={() =>
(document.querySelector("#cdrom-input") as any).click()
}
>
Mount image...
</button>
</div>
</fieldset>
);
}
private renderSmbShare() { private renderSmbShare() {
const { smbSharePath } = this.props; const { smbSharePath } = this.props;
@@ -203,6 +253,19 @@ export class CardSettings extends React.Component<
} }
} }
private onChangeCdrom(event: React.ChangeEvent<HTMLInputElement>) {
const cdromFile =
event.target.files && event.target.files.length > 0
? event.target.files[0]
: null;
if (cdromFile) {
this.props.setCdrom(cdromFile);
} else {
console.log(`Cdrom: Input changed but no file selected`);
}
}
private async onResetState() { private async onResetState() {
await resetState(); await resetState();
this.setState({ isStateReset: true }); this.setState({ isStateReset: true });

View File

@@ -210,7 +210,7 @@ export class Emulator extends React.Component<{}, EmulatorState> {
* 🤡 * 🤡
*/ */
public renderUI() { public renderUI() {
const { isRunning, currentUiCard, floppyFile } = this.state; const { isRunning, currentUiCard, floppyFile, cdromFile } = this.state;
if (isRunning) { if (isRunning) {
return null; return null;
@@ -225,6 +225,7 @@ export class Emulator extends React.Component<{}, EmulatorState> {
card = ( card = (
<CardSettings <CardSettings
setFloppy={(floppyFile) => this.setState({ floppyFile })} setFloppy={(floppyFile) => this.setState({ floppyFile })}
setCdrom={(cdromFile) => this.setState({ cdromFile })}
setSmbSharePath={(smbSharePath) => { setSmbSharePath={(smbSharePath) => {
this.setState({ smbSharePath }); this.setState({ smbSharePath });
ipcRenderer.invoke(IPC_COMMANDS.SET_SMB_SHARE_PATH, smbSharePath); ipcRenderer.invoke(IPC_COMMANDS.SET_SMB_SHARE_PATH, smbSharePath);
@@ -232,6 +233,7 @@ export class Emulator extends React.Component<{}, EmulatorState> {
pickFolder={() => ipcRenderer.invoke(IPC_COMMANDS.PICK_FOLDER)} pickFolder={() => ipcRenderer.invoke(IPC_COMMANDS.PICK_FOLDER)}
bootFromScratch={this.bootFromScratch} bootFromScratch={this.bootFromScratch}
floppy={floppyFile} floppy={floppyFile}
cdrom={cdromFile}
smbSharePath={this.state.smbSharePath} smbSharePath={this.state.smbSharePath}
navigate={navigate} navigate={navigate}
/> />